在Linux上,使用fgets会导致read()调用变长的问题

5

我正在使用fgets读取相当大的文本行(长达128K)。在服务器上,我看到过多的上下文切换,使用strace,我看到以下内容:

read(3, "9005 10218 00840023102015 201008"..., 4096) = 4096

fgets 每次读取 4096 字节的数据块。是否有办法控制 fgets 在调用 read() 时使用的数据块大小?

2个回答

7

setvbuf 是一个很明显的起点。


我想要一个缓冲区,但是希望以稍小的块大小发出读取请求。使用setvbuf函数,我必须设置缓冲区的最大大小,并且读取操作是按照缓冲区的大小进行的(例如,128k的缓冲区会以128k的块大小发出读取请求,在我的情况下实际上表现得比每次读取8192字节更差)。 - Anonym

2

函数fgets()是stdio包的一部分,因此它必须以与使用fgetc()fscanf()fread()等函数一致的方式缓冲(或不缓冲)输入流。这意味着缓冲区本身(如果流被缓冲)是FILE对象的属性。

是否有缓冲区,如果有缓冲区,则缓冲区的大小可以通过调用setvbuf()来建议库。

库实现在忽略提示并执行其认为最佳的操作方面具有相当大的自由度,但通常会接受“合理”的二的幂大小的缓冲区。您已经注意到默认值为4096,这显然比最优解要小。

如果在实际文件上打开流,则默认情况下对其进行缓冲。在管道、FIFO、TTY或其他任何可能具有不同默认值的东西上缓冲。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接