文件的分片上传
格外功能是:秒传,断点续传。
今天最惨,上午找bug,下午一直在修改,晚上脑子what了,混乱的很,数据表之间的逻辑不清晰,导致我传值,还有操作数据库一直有问题,这里最大的问题就是文件唯一了,然后要单独建立一个file表,不与班级,有关,班级文件表可以单独建立,可是当时想着把正在上传的和已经上传的建立了两张表,现在想想都后悔,如果要修改,好多要改的,所以就将就使用两张表吧。
8/4:今天一上午都在检查bug都没解决,现在终于解决:
1:由于我的socket是new的一个,导致我发请求在同一个返回的请求类型(当我得到服务器可以上传文件信息时,
我立刻上传文件所有分片,当我的分片发完,后立刻发文件上传完成请求(这时候又是发送在原来的socket里面)
当服务端接受到文件上传完成,立刻合并分片,会导致导致我new的哪个socket里的请求,上传文件程序还没有
完成,导致我的文件分片列表files里为null
2:在合并文件时,我直接对文件分片进行Array.sort(),这样导致文件合片顺序错误,part11 < part12 < part2
文件分片代码:
public static void splitFile(File file,String md5) throws IOException {
int partCounter = 0;
byte[] buffer = new byte[CHUNK_SIZE];
String fileName = file.getName();
//创建目录
File dir = new File("src/file/" + md5);
if (!dir.exists()) {
boolean created = dir.mkdirs(); // 创建目录及必要的父目录
if (!created) {
throw new IOException("Failed to create directory: " + dir.getAbsolutePath());
}
}
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis)) {
int bytesAmount = 0;
while ((bytesAmount = bis.read(buffer)) > 0) {
String filePartName = String.format("%s.part%d", md5, partCounter++);
File newFile = new File(dir, filePartName);
try (FileOutputStream out = new FileOutputStream(newFile)) {
out.write(buffer, 0, bytesAmount);
}
}
}
这样就可以创建很多分片,然后可以分部上传。
在我上传文件时,是不接受服务端返回的消息,直接发送所有消息的,有问题。后面再修改。
这里暂停上传时,要修改一下。
在上传完成之后
服务端进行文件合并
public static File fileMerge(MyLargerFile myLargerFile) throws IOException {
File newFile = new File("src/resource/files/" +myLargerFile.getMd5()+"."+myLargerFile.getOriginalName());
File[] files = new File("src/resource/file/" +myLargerFile.getMd5()+"part").listFiles();
Arrays.sort(files, (f1, f2) -> {
// 分割文件名,获取分片编号部分
String[] parts1 = f1.getName().split("\\.part");
String[] parts2 = f2.getName().split("\\.part");
// 提取并解析分片编号
int part1 = Integer.parseInt(parts1[1]);
int part2 = Integer.parseInt(parts2[1]);
// 比较分片编号
return Integer.compare(part1, part2);
});
try(FileOutputStream out = new FileOutputStream(newFile)) {
for (File file1 : files) {
System.out.println(file1.getName());
try (FileInputStream fis = new FileInputStream(file1);
BufferedInputStream bis = new BufferedInputStream(fis))
{
int bytesAmount = 0;
byte[] buffer = new byte[CHUNK_SIZE];
while ((bytesAmount = bis.read(buffer)) != -1) {
out.write(buffer, 0, bytesAmount);
}
}
}
}
for (File file : files){
deleteFile(file);
}
deleteFile(new File("src/resource/file/" +myLargerFile.getMd5()+"part"));
return newFile;
}
private static void deleteFile(File file){
if (!file.delete()) {
System.out.println("不能删除该文件: " + file.getName());
}
}
混乱点
在这里表有点多,就导致逻辑有点混乱,这里应该先要建立文件上传记录,然后上传完成后修改数据,还有混乱的就是数据的传递,导致客户端和服务端的赋值,处理数据出现问题,这个特别严重,主要还是因为传递的参数过多,导致混淆。
今天还有一个坑就是进行合并文件时,进行文件的排序
Arrays.sort(files, (f1, f2) -> { // 分割文件名,获取分片编号部分 String[] parts1 = f1.getName().split("\\.part"); String[] parts2 = f2.getName().split("\\.part"); // 提取并解析分片编号 int part1 = Integer.parseInt(parts1[1]); int part2 = Integer.parseInt(parts2[1]); // 比较分片编号 return Integer.compare(part1, part2); });