最简单的 Java 实现文件合并与拆分
引发
某网盘免费用户限制上传文件的大小为 100M,导致我的一些大文件无法上传。本来可以用压缩包分卷的形式上传文件的,但我想探索一下直接的分卷方法。
copy 的启发
copy,字面意思就是“复制”,而Windows 上的 copy 命令却可以合并文件。示例如下:
copy 文件1 + 文件2 + 文件3 文件4 # 或 copy 文件* 文件4 # 其中文件4为合并后的文件
既然是 copy(复制),那么以上代码的意思无非是把多个文件的内容衔接成一个合并的内容,并把它写入一个新文件。
逆向思考
既然合并文件的原理是把多个文件的内容连接成一个内容,那么反过来,把一个文件的内容切分成几个部分,就是拆分文件了。
所以,我们只需要设定分卷的大小,然后按此大小,批量读取其字节,并将每个字节另存为一个分卷。
read(byte[])
发现文件输入流(FileInputStream)中的 read(byte[]) 方法可以迭代读取指定大小的 byte[]。经典用法如下:
// 该方法用于复制文件
File fi = new File(PATH1), fo = new File(PATH2);
FileInputStream fis = new FileInputStream(fi);
FileOutputStream fos = new FileOutputStream(fo);
byte[] part = new byte[1024 * 1024 * 100]; // 设置缓存大小100MB
int bytesRead; // 读取的有效字节长度
while ((bytesRead = fis.read(part)) != -1) {
fos.write(part, 0, bytesRead); // 截取可读的 byte[] 段并写入文件
}
fos.close();
fis.close();
通过缓存的方法迭代读取文件较于直接用 read() 逐字读取更快。
改造经典用法
原复制用法有一个循环体,我们只需要在循环体内做修改,把每次读取到的有效 byte[] 写入一个新文件,即可完成文件拆分。改造用法如下:
// 该方法用于拆分文件
File fi = new File(PATH1);
FileInputStream fis = new FileInputStream(fi);
byte[] part = new byte[1024 * 1024 * 100]; // 设置缓存大小100MB
int bytesRead; // 读取的有效字节长度
int i = 1; // 分卷序号
while ((bytesRead = fis.read(part)) != -1) {
FileOutputStream fos = new FileOutputStream(new File(PATH1 + "." + i + ".part")); // 创建新分卷
fos.write(part, 0, bytesRead); // 截取可读的 byte[] 段并写入新分卷
fos.close(); // 关闭文件输出流
i++;
}
fis.close();
如此即可实现拆分文件。
总结
今天去网上看了许多 Java 拆分文件的方法,差不多都是用 FileInputStream 与 FileOutputStream 实现,但都把读取与写入过程分开实现,显得复杂。今天就算给大家提供一个新思路了。
