RandomAccessFile并发复制文件
RandomAccessFile概述
下面是引自jdk1.6的api中对这个类的描述:
此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。
通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。
代码实现
- 要实现并发复制文件,主要通过RandomAccessFile类的seek方法实现,然后
seek方法描述:
public void seek(long pos)
throws IOException设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。偏移量的设置可能会超出文件末尾。偏移量的设置超出文件末尾不会改变文件的长度。只有在偏移量的设置超出文件末尾的情况下对文件进行写入才会更改其长度。
参数:
pos - 从文件开头以字节为单位测量的偏移量位置,在该位置设置文件指针。
抛出:
IOException - 如果 pos 小于 0 或者发生 I/O 错误。
实现代码
文件复制线程
- 首先要先实现一个文件复制的线程,可以根据源文件路径,目标文件路径,复制文件大小,从文件哪个地方开始复制,代码如下:
/*** 文件复制线程* @author Administrator**/class CopyFileThread implements Runnable{// 源文件路径private String souceFile;// 目标文件路径private String targetFile;// 复制文件长度private Long copyLength;// seek指定文件位置private Long seekIndex;public CopyFileThread(String souceFile, String targetFile, long copyLength , long seekIndex) {this.souceFile = souceFile;this.targetFile = targetFile;this.copyLength = copyLength;this.seekIndex = seekIndex;}@Overridepublic void run() {// 设置读写文件缓冲区,减少文件读写对磁盘的访问次数,提高性能byte [] buffer = new byte[1024];try ( RandomAccessFile souce = new RandomAccessFile(souceFile, "rw") ;RandomAccessFile target = new RandomAccessFile(targetFile, "rw") ;) {// 计算需要读取的文件次数long readCount = copyLength / 1024;for (int i = 0; i < readCount; i++) {if (i != readCount -1 ) {// 不是最后一次时souce.read(buffer);target.write(buffer);} else {// 最后一次时,获取剩余文件长度int tempBufferLength = 1024 + (int)(copyLength % 1024);byte[] tempBuffer = new byte[tempBufferLength];souce.read(tempBuffer);target.write(tempBuffer);}}} catch (Exception e) {e.printStackTrace();} }}
实现并发复制
package io.file;import java.io.RandomAccessFile ;public class CopyFileByRand {// 定义每个线程复制的文件块大小private final int BLOCK = 1024 * 1024 * 64;/*** 多线程复制文件* @param souceFile 源文件存放路径* @param targetFile 复制文件存放路径*/public void currentCopyFile(String souceFile, String targetFile){// jdk7新写法,try()表示最终try块执行完毕之后,()中的资源会被释放,等同于在finally块中释放资源try ( RandomAccessFile source = new RandomAccessFile(souceFile, "rw");RandomAccessFile target = new RandomAccessFile(targetFile, "rw");) {// 获取文件长度 long fileLength = source.length();// 获取需要几个线程进行读取,最后一个线程读取剩余的long count = fileLength / BLOCK;for (int i = 0; i < count; i++) {// 设置目标文件长度target.setLength(fileLength);// "rw" 表示文件可读可写source.seek(i * BLOCK);target.seek(i * BLOCK);// 判断是否是最后一次if (i == count -1) {// 最后一次时,复制文件长度=文件块大小+最后一小块因为fileLength / BLOCK丢失的小数部分文件块大小long copyFileLength = BLOCK + fileLength % BLOCK;// 不是最后一次,文件长度就等于文件块长度new Thread( new CopyFileThread(souceFile, targetFile, copyFileLength, i * BLOCK)).start();} else{// 不是最后一次,文件长度就等于文件块长度new Thread( new CopyFileThread(souceFile, targetFile, BLOCK, i * BLOCK)).start();}}} catch (Exception e) {e.printStackTrace();}}public static void main(String [] args) {CopyFileByRand copy = new CopyFileByRand();copy.currentCopyFile("G:/迅雷下载/变形金刚5.mp4", "E:/变形金刚5.mp4");}
}
RandomAccessFile并发复制文件相关推荐
- ubuntu 终端批量复制文件_《卡死你3000》批量文件复制命令详解
卡死你3000简介: 名词解释: 批量顺序复制文件:从主控机,到从被控机1,被控机2,复制文件.有卡住问题. 批量并发复制文件:从主控机,到从被控机1,被控机2,复制文件.使用多线程并发,可以控制并发 ...
- java正则替换数字_Java 正则表达式,替换图片,替换数字,和谐用语,复制文件...
/** * indexOf("字符",位置int)//在方法中,只输入第一个属性默认从头开始查找属性中的字符,位置int表示从输入的int位置之后查找字符 * lastIndexO ...
- mysql 加快复制进程_MySQL并发复制进程演进
MySQL5.5及以前的复制 一般主从复制有三个线程且都是单线程: Binlog Dump(主) --> IO Thread(从) --> SQL Thread(从). 1.master ...
- Java: 复制文件最快、高效率的方法
Android中的文件复制--视频和图片复制 public class FileOpreateUtils {/*** * @param fromFile 被复制的文件* @param toFile 复 ...
- Java程序片:Java复制文件
第一种方法(输入输出流): public void copyFile(File fromFile,File toFile) throws Exception{FileInputStream in=ne ...
- 综合应用题:多线程复制文件(知识点:多线程、随机读写流)
要求:使用多线程复制一个文件(使用多线程复制一个文件可以加快文件的复制速度) 代码: package 多线程复制文件;import java.io.File; import java.io.FileN ...
- MySQL并发复制系列二:多线程复制
首先梳理下传统MySQL/MariaDB主备复制基本原理: 主从复制通过三个线程来完成,在master节点运行的binlog dump的线程,I/O线程和SQL线程运行在slave 节点 · ...
- hexeditor 复制二进制值_MySQL并发复制演进
MySQL5.5版本及以前的复制一般主从复制有三个线程且都是单线程:Binlog Dump(主)-> IO Thread(从)-> SQL Thread(从). master节点的Binl ...
- cfile file 读写最大文件_java的IO字节流复制文件对比(2)
采纳FileInputStream批量文件复制 和 BufferedInputStream缓冲流的文件复制 // RandomAccessFile 读写操作 public static void ra ...
最新文章
- Python Qt GUI设计:QMainWindow、QWidget和QDialog窗口类(基础篇—10)
- 关于层的挡隔问题的探讨
- java json修改_java – 如何编辑,修改嵌套的JSONObject
- mysql和php的登录注册界面_php实现注册和登录界面的方法
- 永不丢失照片:防弹照片备份的完整指南
- [Bugku][Web][CTF] 16-29 write up
- 系统请求从桌面计算机还原所有数据,电脑怎么一键还原
- 11.CSS border边框
- 【统一异常处理】@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常
- js学习(六)- js对象创建
- ROS-Kinetic安装turtlebot-3并仿真
- (26)基于cookie的登陆认证(写入cookie、删除cookie、登陆后所有域下的网页都可访问、登陆成功跳转至用户开始访问的页面、使用装饰器完成所有页面的登陆认证)...
- 小米手机开发者选项在哪?小米手机怎么打开开发者选项
- linux垃圾文件清理,请问 如何linux 垃圾文件清理、
- Selenium基于Python web自动化测试框架 —— PO模型
- 笛卡尔生平及其成就介绍
- 关于ARM9中的协处理器CP15及MCR/MRC指令
- mysql客户端如何登录_MySQL-客户端登录问题
- 经典案例:卖票问题【线程同步】
- springMVC开发过程中遇到的404错误的两种情况总结