目录
1、文件分片
/**
* 文件分片
*
* @param sourceFilePath 源文件路径
* @param descDirPath 目标文件夹路径
* @param sliceSize 分片大小(byte)
*/
public List<String> splitFile(String sourceFilePath, String descDirPath, long sliceSize) {
if (ObjectUtils.isEmpty(sourceFilePath)) {
throw new BusinessException("sourceFilePath is null, sourceFilePath = " + sourceFilePath);
}
if (ObjectUtils.isEmpty(descDirPath)) {
throw new BusinessException("descDirPath is null, descDirPath = " + descDirPath);
}
File sourceFile = new File(sourceFilePath);
if (!sourceFile.exists()) {
throw new BusinessException("file is not exists, sourceFilePath = " + sourceFilePath);
}
if (sourceFile.isDirectory()) {
throw new BusinessException("source is not file, sourceFilePath = " + sourceFilePath);
}
File descDir = new File(descDirPath);
if (!descDir.exists()) {
descDir.mkdirs();
}
List<String> sliceFilePath = new ArrayList<>();
try (RandomAccessFile raf = new RandomAccessFile(sourceFile, "r")) {
long length = raf.length();//文件的总长度
long offSet = 0L;//初始化偏移量
int index = 0;
while ((length - offSet)/sliceSize != 0) {
long begin = offSet;
long end = begin + sliceSize;
offSet = getWrite(sourceFilePath, descDirPath, index++, begin, end, sliceFilePath);
}
if (length - offSet > 0) {
getWrite(sourceFilePath, descDirPath, index, offSet, length, sliceFilePath);
}
} catch (IOException e) {
throw new BusinessException("file split error", e);
}
return sliceFilePath;
}
/**
* 指定文件每一份的边界,写入不同文件中
* @param sourceFilePath 源文件路径
* @param index 源文件的顺序标识
* @param begin 开始指针的位置
* @param end 结束指针的位置
* @return long
*/
private long getWrite(String sourceFilePath, String descDir, int index, long begin, long end, List<String> sliceFilePath){
File sourceFile = new File(sourceFilePath);
String sourceFileName = sourceFile.getName();
String root = sourceFileName.substring(0, sourceFileName.lastIndexOf(".") + 1);
String descFilePath = descDir + "/" + root + "_" + index + ".tmp";
sliceFilePath.add(descFilePath);
long endPointer = 0L;
try (RandomAccessFile in = new RandomAccessFile(sourceFile, "r");
RandomAccessFile out = new RandomAccessFile(new File(descFilePath), "rw")) {
//申明具体每一文件的字节数组
byte[] b = new byte[1024];
int n = 0;
//从指定位置读取文件字节流
in.seek(begin);
//判断文件流读取的边界
while(in.getFilePointer() <= end && (n = in.read(b)) != -1){
//从指定每一份文件的范围,写入不同的文件
out.write(b, 0, n);
}
//定义当前读取文件的指针
endPointer = in.getFilePointer();
} catch (Exception e) {
e.printStackTrace();
}
return endPointer;
}
2、分片合并
/**
* 文件合并
*
* @param mergeFiles .tmp文件集合
* @param descFilePath 合并后的文件地址
*/
public String mergeFile(List<String> mergeFiles, String descFilePath) {
if (ObjectUtils.isEmpty(mergeFiles)) {
throw new BusinessException("mergeFiles is null");
}
File file = new File(descFilePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
//开始合并文件,对应切片的二进制文件
for (String mergeFile : mergeFiles) {
//读取切片文件
RandomAccessFile reader = new RandomAccessFile(new File(mergeFile), "r");
byte[] b = new byte[1024];
int n = 0;
//先读后写
while ((n = reader.read(b)) != -1) {//读
raf.write(b, 0, n);//写
}
}
} catch (FileNotFoundException ex) {
throw (new BusinessException("file not found:", ex));
} catch (IOException e) {
e.printStackTrace();
}
String type = descFilePath.substring(descFilePath.lastIndexOf(".") + 1);
if (ZIP.equals(type)) {
try (InputStream inputStream = new FileInputStream(descFilePath)){
//ZIP格式直接解压
descFilePath = descFilePath.substring(0, descFilePath.lastIndexOf("."));
unZip(inputStream, descFilePath);
return descFilePath;
} catch (FileNotFoundException ex) {
throw (new BusinessException("file not found:", ex));
} catch (IOException e) {
e.printStackTrace();
}
}
return descFilePath;
}
以上内容为个人学习理解,如有问题,欢迎在评论区指出。