package com.zl.file.operator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author 丢了风筝的线
* @see 文件的分割
* @see 将源文件分为多个子块,然后分次读取这些块,通过RandomAccessFile的seek设置每次开始读取的位置来实现批此读取和写入
*/
public class SplitFile {
// 原文件
private File originalFile;
// 存放的地址
private String destDir;
// 切割后的文件的路径
private List<String> destPaths;
// 每块大小
private int blockSize;
// 多少块
private int count;
public SplitFile(String originalFilePath, String destDir) {
this(originalFilePath, destDir, 1024);
}
public SplitFile(String originalFilePath, String destDir, int blockSize) {
this.originalFile = new File(originalFilePath);
this.destDir = destDir;
this.blockSize = blockSize;
this.destPaths = new ArrayList<String>();
// 初始化
init();
}
private void init() {
// 文件的总大小
long len = this.originalFile.length();
// 块数
this.count = (int) Math.ceil((len * 1.0 / blockSize));
// 切割生成的文件
for (int i = 0; i < this.count; i++) {
this.destPaths.add(this.destDir + "/" + i + "-copy"
+ this.originalFile.getName().substring(this.originalFile.getName().lastIndexOf(".")));
}
}
public void split() throws FileNotFoundException, IOException {
// 每块的起始位置
int beginPos = 0;
// 文件的总大小
long len = this.originalFile.length();
// 每块实际的大小
int actualSize = (int) (len < blockSize ? len : blockSize);
// 每块的起始位置和实际的大小
for (int i = 0; i < this.destPaths.size(); i++) {
// 每块的起始读取位置
beginPos = i * blockSize;
// 最后一块可能不够的情况
if (i == this.destPaths.size() - 1) {
actualSize = (int) len;
} else {
actualSize = blockSize;
len -= actualSize;
}
spiltDatile(i, beginPos, actualSize);
}
}
private void spiltDatile(int i, int beginPos, int actualSize) throws FileNotFoundException, IOException {
// 创建随机访问流对象
RandomAccessFile accessFile = new RandomAccessFile(this.originalFile, "r");
RandomAccessFile accessFile2 = new RandomAccessFile(this.destPaths.get(i), "rw");
accessFile.seek(beginPos);
// 接收每次读取的字节数
byte[] flush = new byte[1024];
// 每次读到的实际长度
int len;
while ((len = accessFile.read(flush)) != -1) {
if (actualSize >= len) {
// 输出到指定的文件中
accessFile2.write(flush, 0, len);
actualSize -= len;
} else {
// 输出到指定的文件中
accessFile2.write(flush, 0, actualSize);
break;
}
}
// 关闭流
accessFile.close();
accessFile2.close();
}
}
java实现文件的分割
最新推荐文章于 2023-09-14 00:00:01 发布