欢迎光临散文网 会员登陆 & 注册

大文件断点续传如何实现?

2023-03-14 19:45 作者:吴小敏63  | 我要投稿

最近接到一个新的需求,需要上传2G左右的视频文件,用测试环境的OSS试了一下,上传需要十几分钟,再考虑到公司的资源问题,果断放弃该方案。

一提到大文件上传,我最先想到的就是各种网盘了,现在大家都喜欢将自己收藏的「小电影」上传到网盘进行保存。网盘一般都支持断点续传和文件秒传功能,减少了网络波动和网络带宽对文件的限制,大大提高了用户体验,让人爱不释手。

说到这,大家先来了解一下这几个概念:

  • 「文件分块」:将大文件拆分成小文件,将小文件上传\下载,最后再将小文件组装成大文件;

  • 「断点续传」:在文件分块的基础上,将每个小文件采用单独的线程进行上传\下载,如果碰到网络故障,可以从已经上传\下载的部分开始继续上传\下载未完成的部分,而没有必要从头开始上传\下载;

  • 「文件秒传」:资源服务器中已经存在该文件,其他人上传时直接返回该文件的URI。

RandomAccessFile

平时我们都会使用FileInputStreamFileOutputStreamFileReader以及FileWriterIO流来读取文件,今天我们来了解一下RandomAccessFile

它是一个直接继承Object的独立的类,底层实现中它实现的是DataInputDataOutput接口。该类支持随机读取文件,随机访问文件类似于文件系统中存储的大字节数组。

它的实现基于「文件指针」(一种游标或者指向隐含数组的索引),文件指针可以通过getFilePointer方法读取,也可以通过seek方法设置。

输入时从文件指针开始读取字节,并使文件指针超过读取的字节,如果写入超过隐含数组当前结尾的输出操作会导致扩展数组。该类有四种模式可供选择:

  • r: 以只读方式打开文件,如果执行写入操作会抛出IOException;

  • rw: 以读、写方式打开文件,如果文件不存在,则尝试创建文件;

  • rws: 以读、写方式打开文件,要求对文件内容或元数据的每次更新都同步写入底层存储设备;

  • rwd: 以读、写方式打开文件,要求对文件内容的每次更新都同步写入底层存储设备;

rw模式下,默认是使用buffer的,只有cache满的或者使用RandomAccessFile.close()关闭流的时候才真正的写到文件。

API

1、void seek(long pos):设置下一次读取或写入时的文件指针偏移量,通俗点说就是指定下次读文件数据的位置。

偏移量可以设置在文件末尾之外,只有在偏移量设置超出文件末尾后,才能通过写入更改文件长度;

2、native long getFilePointer():返回当前文件的光标位置;

3、native long length():返回当前文件的长度;

4、「读」方法

5、「写」方法

6、readFully(byte[] b):这个方法的作用就是将文本中的内容填满这个缓冲区b。如果缓冲b不能被填满,那么读取流的过程将被阻塞,如果发现是流的结尾,那么会抛出异常;

7、FileChannel getChannel():返回与此文件关联的唯一FileChannel对象;

8、int skipBytes(int n):试图跳过n个字节的输入,丢弃跳过的字节;

RandomAccessFile的绝大多数功能,已经被JDK1.4的NIO的「内存映射」文件取代了,即把文件映射到内存后再操作,省去了频繁磁盘io


大文件断点续传如何实现?的评论 (共 条)

分享到微博请遵守国家法律