如果您有内存限制,或者您想要一种通用方法,请从一个文件指针将字节读入缓冲区,进行更改,然后在缓冲区已满时将缓冲区写出到第二个文件指针。如果您在第一个指针上到达 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()
-ed 到两倍大小,以处理累积的编辑。这样,您就可以将昂贵realloc()
的通话费用降至最低。
不知道为什么这被否决了,但它是一种非常可靠的方法,可以处理大量数据。无论如何,希望这对遇到这个问题的人有所帮助。