首先,这是线程类的内容。
public class ThreadReadFile extends Thread {
private File file; // 要读取的文件file
private int start; // 开始的字节数
private int end; // 结束的字节数
private ArrayList<byte[]> list;// 读取到的字节数组存入list集合中
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public ArrayList<byte[]> getList() {
return list;
}
public void setList(ArrayList<byte[]> list) {
this.list = list;
}
// 这里就是要实现的构造方法
public ThreadReadFile(int start, int end, File file) {
this.start = start;
this.end = end;
this.file = file;
this.list = new ArrayList<byte[]>();
}
@Override
public void run() {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] result = new byte[1024];
int num = end - start + 1; //获取要读取的总字节数
fis.skip(start - 1);//跳过之前的字节量
//读取byte数组,并且保存在Arraylist集合中
//每次read后,都会减少总字节数的值,直到完全保存
for (int n = 0; n <= num;) {
if (num <= 1024) {
byte[] result2 = new byte[num];
fis.read(result2);
list.add(result2);
break;
} else {
fis.read(result);
list.add(result);
//注意这里,需要想办法清空byte[]值,不然等再次read的话,在覆盖值的时候会出现无法覆盖的情况
//具体原因还在想,我是采用重新实例化一个对象给它
result = new byte[1024];
num -= 1024;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭输入流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
接下来,用main方法实现多线程读取文件并进行写入复制
public class MainTest {
public static void main(String[] args) throws IOException, InterruptedException {
// 这里是要读取的文件
FileInputStream fis1 = new FileInputStream(file);
// 这里是为了拿到文件的字节数。
int num = fis1.available();
fis1.close();
// 把文件分为3个线程进行读取
ThreadReadFile thread1 = new ThreadReadFile(1, num / 3, file);
ThreadReadFile thread2 = new ThreadReadFile(num / 3 + 1, num / 3 * 2, file);
ThreadReadFile thread3 = new ThreadReadFile(num / 3 * 2 + 1, num, file);
// 启动3个线程
thread1.start();
thread2.start();
thread3.start();
// 在线程运行的同时建立FileOutputStream输出流等待存入文件
// 这里是要复制的文件路径
File file2 = new File("D:/copy/" + file.getName());
file2.createNewFile();
FileOutputStream fos = new FileOutputStream(file2);
// 通过join方法可以让主线程在thread进行死亡后再执行list的赋值操作,以下3个线程同理
thread1.join();
thread2.join();
thread3.join();
ArrayList<byte[]> list = thread1.getList();
list.addAll(thread2.getList());
list.addAll(thread3.getList());
// 文件存入
for (byte[] value : list) {
fos.write(value);
}
fos.flush();
// 关闭输出流,程序结束
fos.close();
}
}