mirror of
https://gitee.com/dromara/hutool.git
synced 2025-08-20 00:44:27 +08:00
Pre Merge pull request !1369 from xy/v5-master
This commit is contained in:
commit
27b7c74f05
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user