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

标签 c file

我正在编写一个处理非常大的用户生成的输入文件的应用程序。该程序将复制大约 95% 的文件,有效地复制它并在副本中切换一些单词和值,然后将副本(以 block 的形式)附加到原始文件,这样每个 block (由 10 到 50 lines) in the original 之后是复制和修改的 block ,然后是下一个原始 block ,依此类推。用户生成的输入符合某种格式,原始文件中任何一行的长度都不太可能超过 100 个字符。

哪种方法更好?

  1. 使用一个文件指针,并使用保存当前位置的变量读取了多少和写入到哪里,来回寻找文件指针进行读写;或者

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

我最关心的是程序的效率,因为输入文件将达到 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/

相关文章:

java - 如何使用java在同一目录中创建多个同名文件?

python只将最后的输出写入文件

c - 在 C/C++ 中使用 libcurl 下载文件

python - 在方法之间读/写文件

python - 从命令行禁用对 python 程序的文件访问

c - 我在 64 位机器上优化 memset 的尝试花费了比标准实现更多的时间。有人可以解释为什么吗?

在程序c中捕获shell脚本输出

c - fgets + 标准输入 : Is it possible to skip first 2 characters?

c - C 中此通用堆栈实现的 "free"函数有什么问题?

c - 数组指针如何存储它的大小?