java多线程复制文件的实例代码
发布时间:2022-03-04 04:29:54
标签:java,多线程,复制
package com.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileCoper {
private static final String _ORIGIN_FILE_MODE = "r";
private static final String _TARGET_FILE_MODE = "rw";
private static long time1 = 0l;
private String originFileName;
private String targetFileName;
private RandomAccessFile originFile;
private RandomAccessFile targetFile;
private int threadCount;
private static int totalThreadCount = 0;
private static int executedCount = 0;
public FileCoper() {
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public FileCoper(String originFile, String targetFile) {
try {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public FileCoper(String originFile, String targetFile, int threadCount) {
try {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void init(String originFile, String targetFile) throws Exception {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public void init(String originFile, String targetFile, int threadCount) throws Exception {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = threadCount;
totalThreadCount = this.threadCount;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile, int threadCount) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.threadCount = threadCount;
totalThreadCount = this.threadCount;
}
public static synchronized void finish() {
FileCoper.executedCount ++;
System.out.println("总线程【" + FileCoper.totalThreadCount + "】,已经完成【" + FileCoper.executedCount + "】个线程的复制!!!");
if (FileCoper.totalThreadCount == FileCoper.executedCount){
long time2 = System.currentTimeMillis();
System.out.println("花费时长:"+(time2-time1));
System.out.println("所有【" + FileCoper.totalThreadCount + "】线程复制完成!!!");
}
}
public void start() throws Exception {
if (this.originFile.length() == 0)
return;
if (this.threadCount == 0)
this.threadCount = 1;
// 设置目标文件大小
this.targetFile.setLength(this.originFile.length());
this.targetFile.seek(0);
this.originFile.seek(0);
time1 = System.currentTimeMillis();
System.out.println(this.originFile.length());
// 把文件分块,每一块有一对值:当前块在文件中的起始位置和结束位置
long[][] splits = new long[this.threadCount][2];
long originFileLength = this.originFile.length();
int startPos = 0;
for (int i = 0; i < this.threadCount; i++) {
splits[i][0] = 0;
splits[i][1] = 0;
if (i == 0) {
splits[i][0] = 0;
splits[i][1] = originFileLength / this.threadCount;
} else if (i == this.threadCount - 1) {
// 注意:此处不能加1,如果加1,线程多文件就会出现乱码
// splits[i][0] = startPos + 1;
splits[i][0] = startPos;
splits[i][1] = originFileLength;
} else {
// 注意:此处不能加1,如果加1,线程多文件就会出现乱码
// splits[i][0] = startPos + 1;
splits[i][0] = startPos;
splits[i][1] = startPos + originFileLength / this.threadCount;
}
startPos += originFileLength / this.threadCount;
// System.out.println(splits[i][0] + " " + splits[i][1]);
Coper fc = new Coper("thread-" + i);
fc.init(this.originFile, this.targetFile, splits[i][0], splits[i][1]);
fc.setOriginFileName(this.originFileName);
fc.setTargetFileName(this.targetFileName);
fc.start();
}
}
public void startNew() throws Exception {
if (this.originFile.length() == 0)
return;
// 设置目标文件大小
this.targetFile.setLength(this.originFile.length());
this.targetFile.seek(0);
this.originFile.seek(0);
long startPosition;
long endPosition;
long block = this.originFile.length() / 1029;
if (block <= 1)
this.threadCount = 1;
for (int i = 0; i < this.threadCount; i++) {
// 定义每次转移的长度
startPosition = i * 1029 * (block / this.threadCount);
endPosition = (i + 1) * 1029 * (block / this.threadCount);
if (i == (this.threadCount - 1))
endPosition = this.originFile.length();
Coper fc = new Coper("thread-" + i);
fc.init(this.originFile, this.targetFile, startPosition, endPosition);
fc.setOriginFileName(this.originFileName);
fc.setTargetFileName(this.targetFileName);
fc.start();
}
}
private class Coper extends Thread {
private String originFileName;
private String targetFileName;
private RandomAccessFile originFile;
private RandomAccessFile targetFile;
private String threadId;
private long startPosition;
private long endPosition;
private long blockCapacity;
public void setOriginFileName(String originFileName) {
this.originFileName = originFileName;
}
public void setTargetFileName(String targetFileName) {
this.targetFileName = targetFileName;
}
public Coper(String threadId) {
this.threadId = threadId;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile, long startPosition, long endPosition) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.blockCapacity = this.endPosition - this.startPosition;
}
public void run() {
// System.out.println(this.threadId + " 启动,开始复制文件【" +
// this.originFileName + "】中的文件块【" + this.startPosition + "," +
// this.endPosition + "】到目标文件【" + this.targetFileName + "】中...");
synchronized (this.originFile) {
try {
// 记录当前拷贝的字节数
int copyCount = 0;
// 数据拷贝的启示偏移量
long offSet = this.startPosition;
byte[] b = new byte[16 * 1024 * 1024];
// 动态设置一次读取的字节数缓冲
long blockSize = 0;
while (copyCount < this.blockCapacity) {
this.originFile.seek(offSet);
if (this.blockCapacity - copyCount > 16 * 1024 * 1024)
blockSize = 16 * 1024 * 1024;
else
blockSize = this.blockCapacity - copyCount;
if (blockSize > this.blockCapacity - copyCount)
blockSize = this.blockCapacity - copyCount;
int count = this.originFile.read(b, 0, (int) blockSize);
synchronized (this.targetFile) {
try {
if (copyCount == 0)
this.targetFile.seek(offSet);
else
this.targetFile.seek(offSet + 1);
this.targetFile.write(b, 0, count);
} catch (IOException e) {
e.printStackTrace();
}
}
// 增加拷贝的字节数
copyCount += count;
// 拷贝其实【偏移量下移
offSet += count;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// System.out.println(this.threadId + " 复制文件【" + this.originFileName
// + "】中的文件块【" + this.startPosition + "," + this.endPosition +
// "】到目标文件【" + this.targetFileName + "】完成!");
// 通知主线程,当前线程完成复制工作
FileCoper.finish();
}
}
public static void main(String[] args) throws Exception {
FileCoper fc = new FileCoper();
fc.init("e:/InitialData_zhihuan.sql", "e:/InitialData_zhihuan2.sql", 30);
//fc.init("d:/ValueAdd_11.txt", "d:/ValueAdd_111.txt", 100);
// fc.init("D:\tools\music\做你的爱人.mp3", "d:/做你的爱人_5.mp3", 10);
//fc.init("E:\电影\最黑暗侵袭.rmvb", "d:/最黑暗侵袭_1.rmvb", 100);
/* // 读入键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 文件来源
String originFile;
// 文件目标
String targetFile;
System.out.println("【源文件、目标文件、线程数】");
System.out.print("要复制的源文件:");
originFile = br.readLine();
System.out.print("文件复制到目标文件:");
targetFile = br.readLine();
System.out.print("切分线程数:");
int threadCount = Integer.parseInt(br.readLine());
fc.init(originFile, targetFile, threadCount);*/
// fc.startNew();
long time1 = System.currentTimeMillis();
fc.start();
long time2 = System.currentTimeMillis();
System.out.println(time2-time1);
}
}
0
投稿
猜你喜欢
- SSM Mapper查询出返回数据查不到个别字段原因开启了驼峰命名法则,Bean里的字段不识别_注释掉或者把实体类里的字段_去掉换位大写SS
- 本文实例为大家分享了Java实现猜数字游戏的具体代码,供大家参考,具体内容如下完成猜数字游戏需要实现以下几点:获得一个随机数作为“答案数”;
- 访问控制:private 私有的protected 受保护的public 公共的类、方法和变量修饰符abstract 声明抽象class 类
- java 中锁的性能提高办法我们努力为自己的产品所遇到的问题思考解决办法,但在这篇文章中我将给大家分享几种常用的技术,包括分离锁、并行数据结
- 前言:根据ThreadPoolExecutor的构造方法,JDK提供了很多工厂方法来创建各种用途的线程池.1 newFixedThreadP
- 为什么需要 StreamStream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 Output
- 一、选择结构大纲if单选择结构if双选择结构if多选择结构嵌套的if结构switch多选择结构二、if单选择结构我们很多时候需要去判断一个东
- java中的LIST在删除时,一般会用list.remove(o); 但这样往往会出现问题,先来看下面的这段代码:package com.d
- 我们平时使用的一些常见队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了De
- 需求基于MTK8163 8.1平台定制导航栏部分,在左边增加音量减,右边增加音量加思路需求开始做之前,一定要研读SystemUI Navig
- 其实本没有没打算写这篇的,但还是要写一下写这篇博客的起因是因为,现在呆着的这家公司居然没有统一的API返回格式?,询问主管他居然告诉我用HT
- 用的Idea,在写MyBatis时,测试发现有以下的报错信息Error parsing SQL Mapper Configuration.
- Java基于对象流实现银行系统的具体代码,供大家参考,具体内容如下系统特点:数据持久化到文件中,系统启动后,加载文件中数据到集合中,相当于做
- 场景既然要搞懂Redis分布式锁,那肯定要有一个需要它的场景。高并发售票问题就是一个经典案例。搭建环境准备redis服务,设置redis的键
- jol(java object layout)需要的依赖<dependency> <
- 前言 短时间提升自己最快的手段就是背面试题,最近总结了Java常用的面试题,分享给大家,希望大家都能圆梦大厂,加油,我命由我不由天
- 方式一public class Test{ public static void main(String[] args) throws Ex
- JAVA操作XML文档主要有四种方式,分别是DOM、SAX、JDOM和DOM4J,DOM和SAX是官方提供的,而JDOM和DOM4J则是引用
- 1.SQL注入:程序向后台数据库传递SQL时,用户提交的数据直接拼接到SQL语句中并执行,从而导入SQL注入攻击。字符型注入:黑色部分为拼接
- java解析json数组最简单的json数组[ { &quo