在linux中,需要合并多个文件,一般情况下使用cat合并即可,但是在超大文件合并的时候cat的速度显得有点慢,还因为读写操作会遇到IO瓶颈。是否有更快的合并方法呢?
尝试过使用fcat(rust工具号称比cat快三倍),测试速度也不理想。
我设想了一种理想的合并方式,就是将上一个文件的最后一个字符的地址与下一个文件的第一个字符的地址连接,两个文件本质上在磁盘上的位置不动,完全不涉及IO,世界上有这种合并方式吗?
如果在本地磁盘上合并超大文件(几十GB-几百GB)推荐基于sendfile()+O_DIRECT的高效零拷贝合并
适用场景:
使用 sendfile() 进行内核态数据传输,避免用户态的读写操作,提高合并速度。同时结合 O_DIRECT 选项,让数据直接从磁盘读写,不经过操作系统缓存,减少 CPU 负担。
编写一个 C 语言程序,利用 sendfile() 进行超高速文件合并:
#include <fcntl.h>
#include <unistd.h>
#include <sys/sendfile.h>
#include <stdio.h>
#include <stdlib.h>
void merge_files(const char *output_file, const char **input_files, int num_files) {
int out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_DIRECT, 0644);
if (out_fd < 0) {
perror("Failed to open output file");
exit(1);
}
for (int i = 0; i < num_files; i++) {
int in_fd = open(input_files[i], O_RDONLY | O_DIRECT);
if (in_fd < 0) {
perror("Failed to open input file");
continue;
}
off_t offset = 0;
struct stat st;
fstat(in_fd, &st);
sendfile(out_fd, in_fd, &offset, st.st_size); // 内核级文件复制
close(in_fd);
}
close(out_fd);
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s output_file input_file1 input_file2 ...\n", argv[0]);
return 1;
}
merge_files(argv[1], (const char **) &argv[2], argc - 2);
return 0;
}
1.编译代码
gcc -o fast_merge fast_merge.c
2.执行合并
./fast_merge merged_file.bin file1.bin file2.bin file3.bin
补充
我上面的例子用了.bin 代表 二进制文件,适用于任何类型的数据,避免格式歧义。如果你的数据是文本,可以换成.txt,如果是日志,可以换成 .log,根据你的需求修改。
7 回答4.8k 阅读
2 回答8k 阅读✓ 已解决
5 回答2.9k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
4 回答3.6k 阅读
1 回答5.6k 阅读✓ 已解决
2 回答5.6k 阅读✓ 已解决
合并多个文件使用多线程跑seek+write会比直接用linux命令快很多