我正在编写一个处理非常大的用户生成的输入文件的应用程序。该程序将复制大约 95% 的文件,有效地复制它并在副本中切换一些单词和值,然后将副本(以 block 的形式)附加到原始文件,这样每个 block (由 10 到 50 lines) in the original 之后是复制和修改的 block ,然后是下一个原始 block ,依此类推。用户生成的输入符合某种格式,原始文件中任何一行的长度都不太可能超过 100 个字符。
哪种方法更好?
使用一个文件指针,并使用保存当前位置的变量读取了多少和写入到哪里,来回寻找文件指针进行读写;或者
使用多个文件指针,一个用于读取,一个用于写入。
我最关心的是程序的效率,因为输入文件将达到 25,000 行,每行大约 50 个字符。
最佳答案
如果您有内存限制,或者您想要一种通用方法,请从一个文件指针将字节读入缓冲区,进行更改,并在缓冲区已满时将缓冲区写出到第二个文件指针。如果您在第一个指针上到达 EOF,请进行更改并将缓冲区中的所有内容刷新到输出指针。如果您打算替换原始文件,请将输出文件复制到输入文件并删除输出文件。这种“原子”方法可让您在删除任何内容之前检查复制操作是否正确进行。
例如,要处理一般复制任意数量的字节,比如一次 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);
处理调整大小的缓冲区的有效方法是保留第二个指针,例如 unsigned char *copyBuffer
,它是 realloc()
的两倍大小,如有必要,以处理累积的编辑。这样,您就可以将昂贵的 realloc()
调用保持在最低限度。
不确定为什么这会被否决,但这是处理一般数据量的一种非常可靠的方法。无论如何,希望这对遇到这个问题的人有所帮助。
关于c - C语言读写大文件的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13498233/