package com.xin.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StepWriteFile {
/**
* 需要读取的目标文件
*/
private String source;
/**
* 将文件写入到具体的目标位置
*/
private String target;
/**
* 单个分片的大小
*/
private Long size;
/**
* 文件
*/
private File file;
private Long readTotal=0L;
/**
* 记录当前写入到文件的哪个位置了
*/
private Long writeSeek = 0L;
private ExecutorService executorService;
public StepWriteFile(String source, String target,Long size) {
this.source = source;
this.target = target;
this.size=size;
executorService = Executors.newFixedThreadPool(6);
this.file = new File(source);
}
/**
* 分片详情信息
*/
class Slice implements Comparable<Slice>{
/**
* 分片的第几部分
*/
private Integer sort;
/**
* 分片字节数组
*/
private byte[] bytes;
/**
* 本次读取的大小
*/
private Integer readSize;
/**
* 当前分片是从哪一个位置开始读取的
*/
private Long readSeek =0l;
@Override
public int compareTo(Slice o) {
return this.sort-o.sort;
}
}
/**
* 分片读取文件的任务类
*/
class ReadFileTask implements Callable<Boolean>{
private List<Slice> fileList;
private RandomAccessFile targetFile;
private CountDownLatch countDownLatch;
public ReadFileTask(List<Slice> fileList, RandomAccessFile targetFile,CountDownLatch countDownLatch) {
this.fileList = fileList;
this.targetFile = targetFile;
this.countDownLatch=countDownLatch;
}
@Override
public Boolean call() throws Exception {
try {
byte[] bytes = null;
//如果当前还支持创建一个预定义分区大小的字节数组
if (file.length()-readTotal>=size){
bytes= new byte[Math.toIntExact(size)];
}
else {
bytes=new byte[(int) (file.length()-readTotal)];
}
Slice slice = new Slice();
synchronized ("suo"){
readTotal+=bytes.length;
targetFile.seek(readTotal-bytes.length);
slice.sort= Math.toIntExact(readTotal - bytes.length);
slice.readSeek=readTotal-bytes.length;
}
int read = targetFile.read(bytes);
synchronized ("锁"){
System.out.println("读取的文件大小\t"+read);
slice.readSize=read;
slice.bytes=bytes;
fileList.add(slice);
countDownLatch.countDown();
}
return true;
}catch (Exception e){
e.printStackTrace();
System.out.println("出现了异常");
return false;
}
}
}
/**
* 根据每个分片读取的文件大小,计算出一共需要几条线程
* @return
*/
private Integer getThreadCount(){
long length = this.file.length();
if (length%size==0) {
return Math.toIntExact(length / size);
}
return Math.toIntExact(length/size+1);
}
/**
* 上传文件
* @return
*/
public boolean uploadFile() throws InterruptedException, IOException {
//该文件一共需要几条线程进行上传
Integer threadCount = this.getThreadCount();
//读取文件获取每个文件段的文件内容
List<Slice> sliceList = this.readFileToList(threadCount);
//将文件内容上传到指定目录
RandomAccessFile randomAccessFile = new RandomAccessFile(target,"rw");
return this.writeFileToTarget(sliceList,randomAccessFile);
}
/**
* 读取文件到list集合中
* @return
*/
private List<Slice> readFileToList(Integer threadCount) throws InterruptedException, FileNotFoundException {
List<Slice> list = new LinkedList<>();
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
List<Callable<Boolean>> callableList = new LinkedList<>();
for (int i = 0; i < threadCount; i++) {
RandomAccessFile randomAccessFile = new RandomAccessFile(source,"rw");
ReadFileTask readFileTask = new ReadFileTask(list,randomAccessFile,countDownLatch);
callableList.add(readFileTask);
}
executorService.invokeAll(callableList);
countDownLatch.await();
return list;
}
/*
* Long totalSize = 0L;
for (Slice slice : sliceList) {
randomAccessFile.write(slice.bytes);
totalSize+=slice.readSize;
randomAccessFile.seek(totalSize);
}
randomAccessFile.close();
* */
/**
* 将文件上传到指定目录位置
* @param sliceList
* @param randomAccessFile
* @return
*/
private boolean writeFileToTarget(List<Slice> sliceList,RandomAccessFile randomAccessFile) throws InterruptedException, IOException {
System.out.println("开始写文件开始写文件");
Collections.sort(sliceList);
for (Slice slice : sliceList) {
randomAccessFile.seek(slice.readSeek);
randomAccessFile.write(slice.bytes);
}
executorService.shutdownNow();
System.out.println("文件写入成功");
return true;
}
}
08-05
1380
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交