关键字: RandomAccessFile

一、作用:

随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问。

二、随机访问文件原理:

首先把随机访问的文件对象看作存储在文件系统中的一个大型 byte 数组,然后通过指向该 byte 数组的光标或索引(即:文件指针 FilePointer)在该数组任意位置读取或写入任意数据。

三、相关方法说明:

1、对象声明:RandomAccessFile raf = newRandomAccessFile(File file, String mode);

其中参数 mode 的值可选 "r":可读,"w" :可写,"rw":可读性;

2、获取当前文件指针位置:int RandowAccessFile.getFilePointer();

3、改变文件指针位置(相对位置、绝对位置):

1> 绝对位置:RandowAccessFile.seek(int index);

2> 相对位置:RandowAccessFile.skipByte(int step);         相对当前位置

4、给写入文件预留空间:RandowAccessFile.setLength(long len);

断点续传实现原理:

1)下载断开的时候,记录文件断点的位置position;

2)继续下载的时候,通过RandomAccessFile找到之前的position位置开始下载

实际操作:

我们在D盘的根目录下创建一个名为”test.txt”的文件,文件内容很简单,如图所示:

没错,我们输入的内容就是简单的6个英语字母。然后我们右键→属性:

我们要实现的效果很简单:将在D盘的”test.txt”文件写入到E盘当中,但中途我们会模拟一次”中断”行为,然后在重新继续上传,最终完成整个过程。

也就是说,我们这里将会把“D盘”视作一台电脑,并且直接将”E盘”视作一台服务器。那么这样我们甚至都不再与http协议扯上半毛钱关系了,(当然实际开发我们肯定是还是得与它扯上关系的 ^

importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.RandomAccessFile;public classTest {private static int position = -1;public static voidmain(String[] args) {//源文件与目标文件

File sourceFile = new File("D:/", "test.txt");

File targetFile= new File("E:/", "test.txt");//输入输出流

FileInputStream fis = null;

FileOutputStream fos= null;//数据缓冲区

byte[] buf = new byte[1];try{

fis= newFileInputStream(sourceFile);

fos= newFileOutputStream(targetFile);//数据读写

while (fis.read(buf) != -1) {

fos.write(buf);//当已经上传了3字节的文件内容时,模拟网络中断了,抛出异常

if (targetFile.length() == 3) {

position= 3;throw newFileAccessException();

}

}

}catch(FileAccessException e) {

keepGoing(sourceFile, targetFile, position);

}catch(FileNotFoundException e) {

System.out.println("指定文件不存在");

}catch(IOException e) {

}finally{try{//关闭输入输出流

if (fis != null)

fis.close();if (fos != null)

fos.close();

}catch(IOException e) {

e.printStackTrace();

}

}

}private static void keepGoing(File source, File target, intposition) {try{

Thread.sleep(10000);

}catch(Exception e) {

e.printStackTrace();

}try{

RandomAccessFile readFile= new RandomAccessFile(source, "rw");

RandomAccessFile writeFile= new RandomAccessFile(target, "rw");

readFile.seek(position);

writeFile.seek(position);//数据缓冲区

byte[] buf = new byte[1];//数据读写

while (readFile.read(buf) != -1) {

writeFile.write(buf);

}

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}class FileAccessException extendsException {

}

总结一下,我们在这次改动当中都做了什么工作:

首先,我们定义了一个变量position,记录在发生中断的时候,已完成读写的位置。(这是为了方便,实际来说肯定应该讲这个值存到文件或者数据库等进行持久化)

然后在文件读写的while循环中,我们去模拟一个中断行为的发生。这里是当targetFile的文件长度为3个字节则模拟抛出一个我们自定义的异常。(我们可以想象为实际下载中,已经上传(下载)了”x”个字节的内容,这个时候网络中断了,那么我们就在网络中断抛出的异常中将”x”记录下来)。

剩下的就如果我们之前说的一样,在“续传”行为开始后,通过RandomAccessFile类来包装我们的文件,然后通过seek将指针指定到之前发生中断的位置进行读写就搞定了。(实际的文件下载上传,我们当然需要将保存的中断值上传给服务器,这个方式通常为httpConnection.setRequestProperty(“RANGE”,”bytes=x”);)

在我们这段代码,开启”续传“行为,即keepGoing方法中:我们起头让线程休眠10秒钟,这正是为了让我们运行程序看到效果。

现在我们运行程序,那么文件就会开启“由D盘上传到E盘的过程”,我们首先点开E盘,会发现的确多了一个test.txt文件,打开它发现内容如下:

没错,这个时候我们发现内容只有“abc”。这是在我们预料以内的,因为我们的程序模拟在文件上传了3个字节的时候发生了中断。

Ok,我们静静的等待10秒钟过去,然后再点开该文件,看看是否能够成功:

通过截图我们发现内容的确已经变成了“abc”,由此也就完成了续传。

java多线程下载文件原理解析+案例

原理解析: 利用RandomAccessFile在本地创建一个随机访问文件,文件大小和服务器要下载的文件大小相同。 根据线程的数量(假设有三个线程),服务器的文件三等分,并把我们在本地创建的文件同样三等分,每个线程下载自己负责的部分,到相应的位置即可。

示例图:

importjava.io.InputStream;importjava.io.RandomAccessFile;importjava.net.HttpURLConnection;importjava.net.URL;public classMutilDownload {private static String path = "http://192.168.80.85:8080/test.doc";private static final int threadCount = 3;public static voidmain(String[] args) {try{

URL url= newURL(path);

HttpURLConnection conn=(HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(5000);int responseCode =conn.getResponseCode();if (responseCode == 200) {int contentLength =conn.getContentLength();

System.out.println("length" +contentLength);

RandomAccessFile rafAccessFile= new RandomAccessFile("test.doc", "rw");

rafAccessFile.setLength(contentLength);int blockSize = contentLength /threadCount;for (int i = 0; i < threadCount; i++) {int startIndex = i * blockSize; //每个现成下载的开始位置

int endIndex = (i + 1) * blockSize - 1;//每个线程的结束位置

if (i == threadCount - 1) {//最后一个线程

endIndex = contentLength - 1;

}newDownloadThread(startIndex, endIndex, i).start();

}

}

}catch(Exception e) {

}

}private static class DownloadThread extendsThread {private intstartIndex;private intendIndex;private intthreadId;public DownloadThread(int startIndex, int endIndex, intthreadId) {this.startIndex =startIndex;this.endIndex =endIndex;this.threadId =threadId;

}

@Overridepublic voidrun() {try{

URL url= newURL(path);

HttpURLConnection conn=(HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(5000);

conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); //固定写法,请求部分资源

int responseCode = conn.getResponseCode(); //206表示请求部分资源

if (responseCode == 206) {

RandomAccessFile rafAccessFile= new RandomAccessFile("test.doc", "rw");

rafAccessFile.seek(startIndex);

InputStream is=conn.getInputStream();int len = -1;byte[] buffer = new byte[1024];while ((len = is.read(buffer)) != -1) {

rafAccessFile.write(buffer,0, len);

}

rafAccessFile.close();

System.out.println("线程" + threadId + "下载完成");

}

}catch(Exception e) {

}

}

}

}

java断点续传原理_java 文件断点续传实现原理相关推荐

  1. java写入写出文件的原理_Java文件断点续传实现原理解析

    一.作用: 随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问. 二.随机访问文件原理: 首先把随机访问的文件对象看作存储在文件系统中的一个大型 byte 数组,然 ...

  2. Windows文件系统中文件的储存原理、文件粉碎机的原理、数据恢复的原理

    首先要明确说明三个问题: Windows文件系统中文件的储存原理.文件粉碎机的原理.数据恢复的原理. Windows文件系统中文件的储存原理:Windows文件系统包括FAT12.FAT16.FAT3 ...

  3. java记事本编程工作原理_Java文件(io)编程之记事本开发详解

    本文实例为大家分享了Java开发简易记事本的具体代码,供大家参考,具体内容如下 public class NotePad extends JFrame implements ActionListene ...

  4. java断点续传 框架_java实现断点续传

    用java的URL实现了一个简单的断点续传的列子,不为别的,假如你对断点续传不了解一看就明白了呵呵,算不上高深啊 package test; import java.io.FileNotFoundEx ...

  5. java 字节缓冲_Java字节缓冲流原理与用法详解

    本文实例讲述了Java字节缓冲流原理与用法.分享给大家供大家参考,具体如下: 一 介绍 BufferInputStresm和BufferOutputStream 这两个流类为IO提供了带缓冲区的操作, ...

  6. java序列化原理_Java序列化机制和原理

    Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...

  7. java用 拼接字符串的原理_Java String 拼接字符串原理详解

    首先来一道思考题: String str1 = "111111"; String str2 = "222222"; String str = str1 + st ...

  8. java jvm原理_JAVA和JVM运行原理

    JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器.它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序. 编译器负责把Java ...

  9. java 内省机制_Java反射及 IoC原理、内省机制

    JAVA反射及IoC原理.JAVA内省 1. 反射反射是框架设计的灵魂,使用前提:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码文件). 1.1 反射概述主要指程序可 ...

最新文章

  1. Centos+PHP模块+exif扩展 (第三方模块)
  2. 视频监控日常使用存在哪些故障
  3. iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码...
  4. JZOJ 3899. 【NOIP2014模拟】逻辑的连通性
  5. nginx反向代理tomcat
  6. truncate、drop、delete区别
  7. php 遍历所有网站网址,使用selenium获取网址所加载所有资源url列表信息
  8. linux安装之后缺少命令,Centos 7 最小安装后关键命令找不到 ifconfig等
  9. 几大经典算法c语言cnds,各种算法的性能分析.docx
  10. “差不多先生”姚劲波和不再神奇的58同城
  11. 微软Media Creation Tool 创建工具 1.3 升级:支持全新下载安装Win11 22H2 Build 22621.525
  12. 计算机网络中特有符号,计算机基础知识测试题-一肖中特免费公开资料.doc
  13. 大数据/云计算 行业报告
  14. 富爸爸穷爸爸--读书笔记
  15. 精读《算法 - 动态规划》
  16. 密码破解神器海德拉GUI界面-xhydra
  17. 四年运维人员的一些唠叨
  18. 计算机辅助翻译优缺点,计算机辅助翻译优缺点
  19. 【ACWing】909. 下棋游戏
  20. 星环云原生数据湖,为企业精准决策提供全方位技术支撑

热门文章

  1. webpack高级应用篇(十四):splitChunks.chunks 中的 async、initial 和 all
  2. 分支定界---branch and bound
  3. 实战!Python 偷偷告诉你小姐姐的听歌喜好
  4. 超超王子和薇薇公主的婚礼
  5. 泰拉瑞亚tModLoader自己开服联机(可加灾厄瑟银mod)
  6. PCB布局布线经验总结2021年2月5日
  7. sdut补题 Ginger的影分身
  8. 源码分享二:STM32风力摆代码 PID | 李萨如合成
  9. 经典面试题---【第一档】
  10. java计算网络吞吐量_Jmeter中的吞吐量计算