文件切片 Java_使用零拷贝对文件高效的切片和合并

对文件的切片/合并在应用中是一个很常见的需求,使用 FileChannel的 transferTo / transferFrom 的零拷贝方法(需要操作系统支持),可以高效的完成。

切片

/**

* 对文件按照指定大小进行分片,在文件所在目录生成分片后的文件块儿

* @param file

* @param chunkSize

* @throws IOException

*/

public static void chunkFile(Path file, long chunkSize) throws IOException {

if (Files.notExists(file) || Files.isDirectory(file)) {

throw new IllegalArgumentException("文件不存在:" + file);

}

if (chunkSize < 1) {

throw new IllegalArgumentException("分片大小不能小于1个字节:" + chunkSize);

}

// 原始文件大小

final long fileSize = Files.size(file);

// 分片数量

final long numberOfChunk = fileSize % chunkSize == 0 ? fileSize / chunkSize : (fileSize / chunkSize) + 1;

// 原始文件名称

final String fileName = file.getFileName().toString();

// 读取原始文件

try(FileChannel fileChannel = FileChannel.open(file, EnumSet.of(StandardOpenOption.READ))){

for (int i = 0; i < numberOfChunk; i++) {

long start = i * chunkSize;

long end = start + chunkSize;

if (end > fileSize) {

end = fileSize;

}

// 分片文件名称

Path chunkFile = Paths.get(fileName + "-" + (i + 1));

try (FileChannel chunkFileChannel = FileChannel.open(file.resolveSibling(chunkFile),

EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))){

// 返回写入的数据长度

fileChannel.transferTo(start, end - start, chunkFileChannel);

}

}

}

}

组合

/**

* 把多个文件合并为一个文件

* @param file目标文件

* @param chunkFiles分片文件

* @throws IOException

*/

public static void mergeFile (Path file, Path ... chunkFiles) throws IOException {

if (chunkFiles == null || chunkFiles.length == 0) {

throw new IllegalArgumentException("分片文件不能为空");

}

try (FileChannel fileChannel = FileChannel.open(file, EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))){

for (Path chunkFile : chunkFiles) {

try(FileChannel chunkChannel = FileChannel.open(chunkFile, EnumSet.of(StandardOpenOption.READ))){

chunkChannel.transferTo(0, chunkChannel.size(), fileChannel);

}

}

}

}

最后

零拷贝

https://zh.wikipedia.org/zh-hans/零复制

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值