Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 直接从文件缓冲区读取_C_Linux_Glibc - Fatal编程技术网

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,让您自己管理所有应用程序端缓冲,例如普通POSIX
open()
read()

因此,我阅读了一些C标准并运行了一些基准测试,以下是我的发现:

1) 按照上述示例中的方法进行操作确实会涉及不必要的内存内复制,这会将基于上述示例的简单
cmp
程序的用户时间增加大约两倍。然而,对于大多数IO密集型程序来说,用户时间无关紧要,除非文件的来源非常快。 然而,在内存中的文件源上(Linux上的
/dev/shm
),当使用接近
buffsiz的buffSize时,关闭
文件
缓冲(
setvbuf(f1,NULL,_IONBF,0);
)确实会在我的机器上产生大约10–15%的良好且一致的速度提升(同样,在IO heavy
cmp
实用程序上根据上面提到的代码片段进行测量,我已经在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的内部流缓冲区”,这可能对像我这样的过早优化的白痴有用。