在C中写/读文件性能问题

时间:2012-11-30 22:41:15

标签: c performance file-io

我在使用C读取和写入文件时遇到了性能问题。这是我的问题和解决方案,但速度很慢:

我有一个ASCII文件,我认为其中的每一行都是记录。我必须根据文件中某个位置的某个数字将此文件拆分为两个。 例如,如果位置10的数字为0,则记录转到file1,如果为1,则记录转到file2。

我所做的是打开输入文件和输出文件的另外两个文件流。我从输入文件中读取一行,进行比较,然后行转到file1或file2,然后读取下一条记录。 它工作正常,但速度很慢。请建议更快地完成此操作的方法。

以下是文件的阅读方式:

bytes_read = readline(infile, (void*)buffer, line_size+1);

fwrite用于写入文件。文件大小约为50 MB。读取整个输入文件后文件将被关闭。

6 个答案:

答案 0 :(得分:1)

你在那里获得了最快捷的方式!

  • 你有什么类型的IO?缓冲/无缓冲?
  • 文件有多大?
  • 您是打开/关闭每一行的输出文件,还是打开它们?
  • 在输出文件中搜索任何内容?
  • 哪个部分很慢,看了吗?写?既?

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)

您可以尝试减少读/写调用次数。

  1. 尝试读取2k字节而不是getline()。如果您的文件不是很大,甚至可以读取整个文件。
  2. 使用缓冲写入。并且每次写入后都不要关闭文件。只有在完成整个文件的写入后才能关闭文件。

答案 5 :(得分:0)

在评论中讨论后,我认为你的问题没有简单的答案。

对数千个大尺寸CSV文件进行有效阅读和写作非常困难。

发明了具有更好存储引擎的数据库,以避免出现类似的性能问题。

也许你应该看看在某些开源数据库中如何设计CSV引擎。在那里你应该找到(非常复杂的)你的问题的答案:处理许多大型csv文件的最佳方法是什么。