关于使用 Java 分片读\写文件
2024-09-04 18:46:51
分片读取文件方法:
/**
* 分片读取文件块
*
* @param path 文件路径
* @param position 角标
* @param blockSize 文件块大小
* @return 文件块内容
*/
public static byte[] read(String path, long position, int blockSize) throws Exception {
// ----- 校验文件,当文件不存在时,抛出文件不存在异常
checkFilePath(path, false);
// ----- 读取文件
ByteBuffer block = ByteBuffer.allocate(blockSize);
try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get(path), StandardOpenOption.READ)) {
Future<Integer> read = channel.read(block, position);
while (!read.isDone()) {
// ----- 睡1毫秒, 不抢占资源
Thread.sleep(1L);
}
}
return block.array();
}
分片写文件方法:
/**
* 分片写文件
*
* @param path 文件目标位置
* @param block 文件块内容
* @param position 角标
* @throws Exception
*/
public static void write(String path, byte[] block, long position) throws Exception {
// ----- 校验文件,当文件不存在时,创建新文件
checkFilePath(path, true);
// ----- 写文件
ByteBuffer buffer = ByteBuffer.wrap(block);
try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get(path), StandardOpenOption.WRITE)) {
Future<Integer> write = channel.write(buffer, position);
while (!write.isDone()) {
// ----- 睡1毫秒, 不抢占资源
Thread.sleep(1L);
}
}
}
检查文件是否存在方法:
/**
* 校验文件
*
* @param path 文件路径
* @param flag 当文件不存在时是否创建文件 [true: 创建文件;false: 抛出文件不存在异常]
* @return
* @throws Exception
*/
public static File checkFilePath(String path, boolean flag) throws Exception {
if (StringUtils.isBlank(path)) {
throw new RuntimeException("The file path cannot be empty.");
}
File file = new File(path);
if (!file.exists()) {
if (flag) {
// ----- 当文件不存在时,创建新文件
if (!file.createNewFile()) {
throw new RuntimeException("Failed to create file.");
}
} else {
// ----- 抛出文件不存在异常
throw new RuntimeException("File does not exist.");
}
}
return file;
}
测试:
/*** 分片读写文件的每片默认大小: 10M */
private static final Integer DEFAULT_BLOCK_SIZE = 1024 * 1024 * 10; public static void main(String[] args) throws Exception {
String path = "F:\\compression\\Spring源码深度解析.pdf";
String toPath = "F:\\compression\\" + System.currentTimeMillis() + ".pdf";
File file = FileUtil.checkFilePath(path, false);
long position = 0, length = file.length();
while (length > DEFAULT_BLOCK_SIZE) {
// ----- 如果文件大小大于默认分块大小,循环读写文件,每次循环读取一块,直到剩余文件大小小于默认分块大小
byte[] block = FileUtil.read(path, position, DEFAULT_BLOCK_SIZE);
FileUtil.write(toPath, block, position);
position += DEFAULT_BLOCK_SIZE;
length -= DEFAULT_BLOCK_SIZE;
}
if (length > 0) {
// ----- 如果文件大小小于默认分块大小且大于零,正常读写文件
byte[] block = FileUtil.read(path, position, (int) length);
FileUtil.write(toPath, block, position);
}
}
最新文章
- JMeter 集合点
- 揭秘史上最完美一步到位的搭建Andoriod开发环境
- IIS 7.5 应用程序池预热模块组件
- 关于js事件委托
- iOS-WKWebView携带cookie发送http请求,cookie失效
- 《Velocity 模板使用指南》中文版[转]
- iptsbles及磁盘扩容
- NetFramework各个版本的特性笔记
- .Net中的AOP系列之《AOP实现类型》
- Java Stream
- 创建一个vue项目的过程
- CentOS7 修改网卡名称为eth0
- SDE与shapefile之间的数据导入与导出
- 解决Database returned an invalid datetime value. Are time zone definitions for your database installed?
- 解决zabbix3.4图表显示中文乱码问题
- MATLAB的一些小技巧
- 38.spiderkeeper的配置
- windows7 Cygwin 下安装 YouCompleteMe 插件
- js-redux学习笔记2
- C# WINFORM的自动更新程序