【六袆-Java】Java 断点续传原理;
文件断点续传,我的理解是文件在传输过程中因为某些原因程序停止运行文件终止传输,下一次重新传输文件的时候还能从上一次传输的位置开始传输,而不需要重新从头开始。
文件传输的时候收到不确定因素的影响,打断传输状态,当再次传输的时候不需要从头开始传,从断掉的地方开始,节省时间,节省资源。
1. 中断时的这个点位怎么记录?
达达:当我们读取的时候,使用 byte 数组作为媒介,循环进行转存,那我们可以将中断时 byte 数组的循环次数作为一个标记存下来。这样就解决了终端点位标记的问题
2. 读取文件时怎么从这个点位开始?
达达:JAVA 提供的了一个文件操作类
java.io.RandomAccessFile
,这个类的定义是 JAVA提供的对文件内容的访问,既可以读文件,也可以写文件。支持随机访问文件,可以访问文件的任意位置
void close() //关闭此随机访问文件流并释放与该流关联的所有系统资源。
int read(byte[] b) // 将最多 b.length 个数据字节从此文件读入 byte 数组。
void seek(long pos) //设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
void write(byte[] b) // 将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。
正常传输
代码解释:定义了一个byte[] 数组来作为缓冲区,大小为1个字节。也就是说读取的时候是一个字节一个字节的读,读完我们的十个数字需要循环读取十遍。
private static void normalTrans(String sourceFilePath, String targetFilePath) {
File sourFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
FileInputStream fis = null;
FileOutputStream fos = null;
byte[] buf = new byte[1];
try {
fis = new FileInputStream(sourFile);
fos = new FileOutputStream(targetFile);
while (fis.read(buf) != -1) {
System.out.println("write dataing ...".toUpperCase());
fos.write(buf);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
中断传输
代码解释:读取全部需要循环十遍,那么我们就在他没读取完毕的时候人为干预,让他停止。这里我是当循环第三遍的时候抛出了异常来中断的。中断之后我们打开,目标文件,发现里面只有前三个数。说明中断成功了。
private static int breakTrans(String sourceFilePath, String targetFilePath) {
int position = -1;
File sourFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
FileInputStream fis = null;
FileOutputStream fos = null;
byte[] buf = new byte[1];
try {
fis = new FileInputStream(sourFile);
fos = new FileOutputStream(targetFile);
while (fis.read(buf) != -1) {
System.out.println("write dataing ...".toUpperCase());
fos.write(buf);
if (targetFile.length() == 3) {// 当目标文件长度写到三的时候,抛出异常,终端传输
position = 3;
throw new Exception();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return position;
}
断点继续传输文件
代码解释:这里使用 RandomAccessFile 来传输,使用 seek 方法来定位继续的位置,然后正常读写。读写完毕之后再打开目标文件,发现十个数已经全都过来了。那么我们断点续传的目的已经达到了。
private static void continueTrans(String sourceFilePath, String targetFilePath, int position) {
File sourFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
RandomAccessFile read = null;
RandomAccessFile write = null;
byte[] buf = new byte[1];
try {
read = new RandomAccessFile(sourFile, "r");
write = new RandomAccessFile(targetFile, "rw");
// 关键,找到位置
read.seek(position);
write.seek(position);
while (read.read(buf) != -1) {
System.out.println("write dataing ...".toUpperCase());
write.write(buf);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (read != null) {
read.close();
}
if (write != null) {
write.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
调用方法
代码解释:里面的 myWhile ,很多人看到这个很纳闷,还能这么写?说白了起始很简单,myWhile 就是给这个 while 循环体起的名字。如果嵌套循环,或者像这种while 里面套 switch case的,在switch 里面break 只会跳出switch 。如果想跳出while 循环,就需要像这样给while 起个名字,然后再break 加上这个名字,告诉break 要跳出的是哪个。
public static void run() {
String sourceFilePath = "1.txt";
String targetFilePath = "2.txt";
int position = 0;
Scanner scanner = new Scanner(System.in);
myWhile: while (true) {
System.out.println("input type:".toUpperCase());
System.out.println("1.normalTrans");
System.out.println("2.breakTrans");
System.out.println("3.continueTrans");
System.out.println("4.quit");
int type = scanner.nextInt();
switch (type) {
case 1:
normalTrans(sourceFilePath, targetFilePath);
break;
case 2:
position = breakTrans(sourceFilePath, targetFilePath);
break;
case 3:
continueTrans(sourceFilePath, targetFilePath, position);
break;
case 4:
break myWhile;
}
}
友情提醒:这里说的只是最简单的断点续传思想,而且这个思想在单线程里面勉强还可以用,但是多线程就Over the car~
本文来自博客园,作者:你好,Alf,转载请注明原文链接:https://www.cnblogs.com/Alf-/p/16192820.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话