如何获取C中从缓存读取的字节数

时间:2016-11-21 19:42:13

标签: c

我有一个简单的C程序,可以循环打开文件:

for(i = 1; i <= loopCount; ++i)
{

   FILE *fp;
   char buff[255];

   fp = fopen("test.txt", "r");
   fgets(buff, 255, (FILE*)fp);
   /* do something */
   fclose(fp);
}

我想知道每次从缓存读取多少字节以及从磁盘读取多少字节并记录它。 (如果有问题,我在Ubuntu 16.04中运行它)有什么方法可以找到它吗?有任何想法吗?

2 个答案:

答案 0 :(得分:2)

这有效:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

long getIORead()
{
    FILE * j = fopen ("/proc/self/io", "r");
    if (j == NULL)
        return -1;

    char buf[256];
    while (fgets(buf, 250, j) != NULL)
        if (strstr(buf, "read_bytes: ") != NULL)
        {
            fclose(j);
            return atol(strchr(buf, ' ') + 1);
        }
    return -1;
}


int main()
{
    unsigned long before, after;
    before = getIORead();

    {
        // code goes here
    }

    after = getIORead();
    printf("Bytes read from disk: %d\n", (int) (after - before));
}

它很丑陋且缺乏良好的错误检查,但这证明了如何做到这一点。

以下是测试代码读取长度为4,095,201字节的文件(未经过多年访问或修改)的结果:

  

$ ./test
  从磁盘读取的字节数:4096000
  $ ./test
  从磁盘读取的字节数:0

正如预期的那样,第一次读取来自磁盘,第二次读取来自缓存。

答案 1 :(得分:0)

使用__fbufsize检索缓冲区的大小。这将允许您计算从缓冲区检索的字节数与从文件中检索的字节数:

for(i = 1; i <= loopCount; ++i) {
   FILE *fp;
   char buff[255];
   fp = fopen("test.txt", "r");
   size_t bsize = __fbufsize(fp);
   size_t remaining = 0;
   while (fgets(buff, 255, fp)) {
       size_t rsize = strlen(buff);
       if (rsize <= remaining) {
           printf("From buffer: %zu, From file: 0", rsize);
           remaining -= rsize;
       } else {
           size_t additional = rsize-remaining;
           printf("From buffer: %zu, From file: %zu", remaining, additional);
           remaining = bsize - additional % bsize;
       }
       /* do something */
   }
   fclose(fp);
}

我们的想法是计算我们在缓冲区中有多少未使用的字节,假设每次缓冲区运行时它都会重新填充容量。

逻辑在循环内的if条件中实现:

  • 第一个分支描述了缓冲区中剩余的数据足以完全满足读取请求的情况。这里我们需要减少缓冲区中剩余的字节数。
  • 第二个分支描述了某些数据(或可能没有数据)来自缓冲区的情况,additional数据来自磁盘。注意当我们获取的字符串大于缓冲区(因此%操作)时代码必须小心的情况。