C 直接从文件缓冲区读取
我的应用程序的核心大致如下所示:C 直接从文件缓冲区读取,c,linux,glibc,C,Linux,Glibc,我的应用程序的核心大致如下所示: size_t bufsize; char* buf1; size_t r1; FILE* f1=fopen("/path/to/file","rb"); ... do{ r1=fread(buf1, 1, bufsize, f1); processChunk(buf1,r1); } while (!feof(f1)); ... (实际上,我有多个文件*和多个bufN)现在,我听说文件已经准备好自行管理缓冲区(称为“流缓冲区”),而且这种行为似乎很容
size_t bufsize;
char* buf1;
size_t r1;
FILE* f1=fopen("/path/to/file","rb");
...
do{
r1=fread(buf1, 1, bufsize, f1);
processChunk(buf1,r1);
} while (!feof(f1));
...
(实际上,我有多个文件*
和多个bufN
)现在,我听说文件
已经准备好自行管理缓冲区(称为“流缓冲区”),而且这种行为似乎很容易调整:
我如何重构上面的代码片段以丢弃
buf1
缓冲区并使用f1
的内部流缓冲区(同时将其设置为bufsize
)?如果您不想使用不透明缓冲的I/O,请不要使用文件*
。使用较低级别的API,让您自己管理所有应用程序端缓冲,例如普通POSIXopen()
和read()
。因此,我阅读了一些C标准并运行了一些基准测试,以下是我的发现:
1) 按照上述示例中的方法进行操作确实会涉及不必要的内存内复制,这会将基于上述示例的简单cmp
程序的用户时间增加大约两倍。然而,对于大多数IO密集型程序来说,用户时间无关紧要,除非文件的来源非常快。
然而,在内存中的文件源上(Linux上的/dev/shm
),当使用接近buffsiz的buffSize时,关闭文件缓冲(setvbuf(f1,NULL,_IONBF,0);
)确实会在我的机器上产生大约10–15%的良好且一致的速度提升(同样,在IO heavycmp
实用程序上根据上面提到的代码片段进行测量,我已经在2个相同的700MB文件上测试了100次)
2) 虽然有一个用于设置文件
缓冲区的API,但我还没有找到任何标准化的API来读取它,因此我将坚持使用真实且经过测试的方法,但是关闭文件
缓冲区(setvbuf(f1,NULL,_IONBF,0);
)
(但我想我可以通过使用_ionbfmode选项(=关闭缓冲)将自己的缓冲区设置为文件流缓冲区来解决我的问题,然后我可以通过文件结构中的一些非标准指针来访问它。)您不应该尝试这样做。使用fread
或fgets
这样做的动机是什么?你可能使用的任何类型的黑客都将是不可靠的、不适合未来的和不可移植的。你试图解决的实际问题是什么?@'Paul R':1)智力好奇心2)我需要一次跟踪多个文件*,一次跟踪多个缓冲区,如果文件*已经有一个指向缓冲区的指针,这似乎会让事情变得更简单。3) 在文件中有一个缓冲区,在代码中有一个缓冲区,这似乎意味着memmory复制是不必要的(当然——如果我正在从HDD读取数据,与HDD io相比,复制几乎是即时的,但仍然是)3)参见1);)用feof
控制循环几乎肯定是错误的。例如,如果发生读取错误,文件的结尾将永远不会出现,但读取将失败。实际上,他似乎想要缓冲:“使用f1的内部流缓冲区”,这可能对像我这样的过早优化的白痴有用。