import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class FileSpiltAndMerge {
public static void main(String[] args) throws IOException {
spilt("D:\\file\\aaa.zip", 1, "D:\\file\\fenpian");
merge("D:\\file\\fenpian", "D:\\file\\hebing.zip");
}
public static void spilt(String from, int size, String to) throws IOException {
File f = new File(from);
FileInputStream in = new FileInputStream(f);
FileOutputStream out = null;
FileChannel inChannel = in.getChannel();
FileChannel outChannel = null;
// 将MB单位转为为字节B
long m = size * 1024 * 1024;
// 计算最终会分成几个文件
int count = (int) (f.length() / m);
for (int i = 0; i <= count; i++) {
// 生成文件的路径
String t = to + "/" + i;
try {
out = new FileOutputStream(new File(t));
outChannel = out.getChannel();
// 从inChannel的m*i处,读取固定长度的数据,写入outChannel
if (i != count)
inChannel.transferTo(m * i, m, outChannel);
else// 最后一个文件,大小不固定,所以需要重新计算长度
inChannel.transferTo(m * i, f.length() - m * count, outChannel);
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
outChannel.close();
}
}
in.close();
inChannel.close();
}
public static void merge(String from, String to) throws IOException {
File t = new File(to);
FileInputStream in = null;
FileChannel inChannel = null;
FileOutputStream out = new FileOutputStream(t, true);
FileChannel outChannel = out.getChannel();
File f = new File(from);
// 获取目录下的每一个文件名,再将每个文件一次写入目标文件
if (f.isDirectory()) {
List<File> list = getAllFileAndSort(from);
// 记录新文件最后一个数据的位置
long start = 0;
for (File file : list) {
in = new FileInputStream(file);
inChannel = in.getChannel();
// 从inChannel中读取file.length()长度的数据,写入outChannel的start处
outChannel.transferFrom(inChannel, start, file.length());
start += file.length();
in.close();
inChannel.close();
}
}
out.close();
outChannel.close();
}
private static List<File> getAllFileAndSort(String dirPath) {
File dirFile = new File(dirPath);
File[] listFiles = dirFile.listFiles();
List<File> list = Arrays.asList(listFiles);
Collections.sort(list, (o1, o2) -> {
return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName());
});
return list;
}
}
如果因大文件请求超时前端进行分片的话后端直接保存分片文件,无需进行分片操作,只进行合并操作
//保存分片文件到指定路径 @PostMapping("/file/upload") R fileUpload(@RequestParam("file") MultipartFile file,String fileName) { //文件保存路径 String path = filePath+getUserId(); File parentFileDir = new File(path); //如果无路径则创建 if (!parentFileDir.exists()) { parentFileDir.mkdirs(); } // 获取文件名(包括后缀) try (FileOutputStream fos = new FileOutputStream(path+"\\" + fileName)) { //写入文件 fos.write(file.getBytes()); return R.ok(); } catch (Exception e) { logger.error(e.getMessage(), e); } return R.error(); }