Pre Merge pull request !1369 from xy/v5-master

This commit is contained in:
xy 2025-07-30 10:52:30 +00:00 committed by Gitee
commit 27b7c74f05
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 117 additions and 0 deletions

View File

@ -0,0 +1,83 @@
package cn.hutool.core.io;
import cn.hutool.core.util.StrUtil;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* 大文件分片处理工具
*/
public class FileSplitUtil {
/**
* 将大文件分割为多个小文件
* @param sourceFile 源文件
* @param chunkSize 每个分片的大小(字节)
* @param targetDir 目标目录
* @return 分片文件列表
*/
public static List<File> split(File sourceFile, long chunkSize, String targetDir) {
if (!sourceFile.exists()) {
throw new IORuntimeException("Source file not exists: " + sourceFile.getAbsolutePath());
}
if (chunkSize <= 0) {
throw new IllegalArgumentException("Chunk size must be positive");
}
List<File> chunkFiles = new ArrayList<>();
String baseName = FileUtil.getPrefix(sourceFile);
String extension = FileUtil.getSuffix(sourceFile);
try (InputStream in = Files.newInputStream(sourceFile.toPath())) {
byte[] buffer = new byte[(int) Math.min(chunkSize, 8192)];
int bytesRead;
int chunkIndex = 0;
long totalBytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
if (totalBytesRead % chunkSize == 0) {
// 开始新的分片
String chunkName = StrUtil.format("{}/{}-{}.{}",
targetDir, baseName, chunkIndex, extension);
File chunkFile = new File(chunkName);
try (OutputStream out = Files.newOutputStream(chunkFile.toPath())) {
out.write(buffer, 0, bytesRead);
}
chunkFiles.add(chunkFile);
chunkIndex++;
} else {
// 继续写入当前分片
File currentChunk = chunkFiles.get(chunkFiles.size() - 1);
try (OutputStream out = new FileOutputStream(currentChunk, true)) {
out.write(buffer, 0, bytesRead);
}
}
totalBytesRead += bytesRead;
}
} catch (IOException e) {
throw new IORuntimeException(e);
}
return chunkFiles;
}
/**
* 合并分片文件
* @param chunkFiles 分片文件列表
* @param targetFile 目标文件
*/
public static void merge(List<File> chunkFiles, File targetFile) {
try (OutputStream out = Files.newOutputStream(targetFile.toPath())) {
for (File chunk : chunkFiles) {
Files.copy(chunk.toPath(), out);
}
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
}

View File

@ -0,0 +1,34 @@
package cn.hutool.core.io;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.file.LineSeparator;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.CharsetUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link FileUtil} 单元测试类
*
* @author Looly
*/
public class FileSplitUtilTest {
@Test
public void fileSplitTest1() {
final File file = FileUtil.file("d:/aaa/123.docx");
List<File> splitFiles = FileSplitUtil.split(file,3072,"d:/bbb");
FileSplitUtil.merge(splitFiles,FileUtil.newFile("d:/ccc/456.docx"));
}
}