用C语言读写大文件的有效方法

我正在编写一个处理非常大的用户生成的输入文件的应用程序。 该程序将复制约95%的文件,有效地复制它并在副本中切换一些单词和值,然后将副本(以块为单位)附加到原始文件,以便每个块(包括10到50之间)在原始的行后面是复制和修改的块,然后是下一个原始块,依此类推。 用户生成的输入符合特定格式,原始文件中的任何行都不可能长于100个字符。

哪种方法更好?

  1. 要使用一个文件指针并使用保存当前位置的变量以及已写入的位置,请来回读取和写入文件指针; 要么

  2. 使用多个文件指针,一个用于读取,一个用于写入。

我主要关注程序的效率,因为输入文件最多可达25,000行,每行大约50个字符。

25000行* 100个字符= 2.5MB,这不是一个巨大的文件。 最快的可能是读取内存中的整个文件并将结果写入新文件并用原始文件替换原始文件。

如果您有内存限制,或者您想要通用方法,请从一个文件指针读取缓冲区中的字节,进行更改,并在缓冲区已满时将缓冲区写入第二个文件指针。 如果在第一个指针上达到EOF,则进行更改并将缓冲区中的任何内容刷新到输出指针。 如果要替换原始文件,请将输出文件复制到输入文件并删除输出文件。 这种“primefaces”方法允许您在删除任何内容之前检查复制操作是否正确进行。

例如,要处理一般复制任意数量的字节,例如,每次1 MiB:

 #define COPY_BUFFER_MAXSIZE 1048576 /* ... */ unsigned char *buffer = NULL; buffer = malloc(COPY_BUFFER_MAXSIZE); if (!buffer) exit(-1); FILE *inFp = fopen(inFilename, "r"); fseek(inFp, 0, SEEK_END); uint64_t fileSize = ftell(inFp); rewind(inFp); FILE *outFp = stdout; /* change this if you don't want to write to standard output */ uint64_t outFileSizeCounter = fileSize; /* we fread() bytes from inFp in COPY_BUFFER_MAXSIZE increments, until there is nothing left to fread() */ do { if (outFileSizeCounter > COPY_BUFFER_MAXSIZE) { fread(buffer, 1, (size_t) COPY_BUFFER_MAXSIZE, inFp); /* -- make changes to buffer contents at this stage -- if you resize the buffer, then copy the buffer and change the following statement to fwrite() the number of bytes in the copy of the buffer */ fwrite(buffer, 1, (size_t) COPY_BUFFER_MAXSIZE, outFp); outFileSizeCounter -= COPY_BUFFER_MAXSIZE; } else { fread(buffer, 1, (size_t) outFileSizeCounter, inFp); /* -- make changes to buffer contents at this stage -- again, make a copy of buffer if it needs resizing, and adjust the fwrite() statement to change the number of bytes that need writing */ fwrite(buffer, 1, (size_t) outFileSizeCounter, outFp); outFileSizeCounter = 0ULL; } } while (outFileSizeCounter > 0); free(buffer); 

处理resize的缓冲区的一种有效方法是保留第二个指针,比如unsigned char *copyBuffer ,如果需要, realloc() unsigned char *copyBuffer大小为两倍,以处理累积的编辑。 这样,您可以将昂贵的realloc()调用保持在最低限度。

不知道为什么这会被推翻,但这是一个非常可靠的方法来处理一般数据量。 希望这可以帮助遇到这个问题的人,无论如何。