我在使用C读取和写入文件时遇到了性能问题。这是我的问题和解决方案,但速度很慢:
我有一个ASCII文件,我认为其中的每一行都是记录。我必须根据文件中某个位置的某个数字将此文件拆分为两个。 例如,如果位置10的数字为0,则记录转到file1,如果为1,则记录转到file2。
我所做的是打开输入文件和输出文件的另外两个文件流。我从输入文件中读取一行,进行比较,然后行转到file1或file2,然后读取下一条记录。 它工作正常,但速度很慢。请建议更快地完成此操作的方法。
以下是文件的阅读方式:
bytes_read = readline(infile, (void*)buffer, line_size+1);
fwrite用于写入文件。文件大小约为50 MB。读取整个输入文件后文件将被关闭。
答案 0 :(得分:1)
你在那里获得了最快捷的方式!
IO是程序中较慢的部分之一。一些代码可以帮助我们发现任何明显的问题。
答案 1 :(得分:1)
如果您正在阅读文件,则最好使用fgets。这会自动移动下一个fgets的文件指针。
fseek和ftell在你的代码中减慢了速度。试试这个。它应该快得多。
#include <stdio.h>
#include <stdlib.h>
int
main()
{
char line[132];
int line_num = 0;
FILE *fp_r, *fp_w1, *fp_w2, *fp_w;
fp_r = fopen("readfile", "r");
if (fp_r == NULL) {
printf("Could not open testfile\n");
exit(0);
}
fp_w1 = fopen("writefile1", "w");
if (fp_w1 == NULL) {
printf("Could not open writefile1\n");
exit(0);
}
fp_w2 = fopen("writefile2", "w");
if (fp_w1 == NULL) {
printf("Could not open writefile2\n");
exit(0);
}
while (fgets(line, sizeof(line), fp_r) != NULL) {
line_num++;
if (*(line+9) == '0') {
fp_w = fp_w1;
}
else if (*(line+9) == '1') {
fp_w = fp_w2;
}
else {
printf("Exiting - Error at line %d\n", line_num);
exit(1);
}
fprintf(fp_w, line);
}
fclose(fp_r);
fclose(fp_w1);
fclose(fp_w2);
exit(0);
}
我使用的读取文件是
01234567 0 This is the line with 0 at position 10
01234567 1 This is the line with 1 at position 10
答案 2 :(得分:0)
您可以尝试以块为单位而不是一行读取文件。块读取可以比逐行读取快得多。如果你可以将整个事物读入记忆中,那很好。如果没有,请阅读一个大块,处理它并继续前进。
答案 3 :(得分:0)
我认为您应该将所有文件读入某些数组并处理变量/数组,而不是直接在IO上工作。
当然,如果可以的话(你的文件很少,而不是数百个)。
如果有数百或数千个这些文件 - 那么您应该考虑另一种数据存储方法。数据库专为此类设计。
另一个选择是使用CSV存储引擎的MySQL。
The CSV Storage Engine at mysql.com
但最后可能会迫使你改变文件结构。
答案 4 :(得分:0)
您可以尝试减少读/写调用次数。
答案 5 :(得分:0)
在评论中讨论后,我认为你的问题没有简单的答案。
对数千个大尺寸CSV文件进行有效阅读和写作非常困难。
发明了具有更好存储引擎的数据库,以避免出现类似的性能问题。
也许你应该看看在某些开源数据库中如何设计CSV引擎。在那里你应该找到(非常复杂的)你的问题的答案:处理许多大型csv文件的最佳方法是什么。