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

如何在C中获取从缓存读取的字节数,c,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); } for(i=1;i用于检索缓冲区的大小。这将允许您计算从缓冲区检索的字节数与从文件检索的字节数: for(i

我有一个简单的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);
}
for(i=1;i用于检索缓冲区的大小。这将允许您计算从缓冲区检索的字节数与从文件检索的字节数:

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);
}
对于(i=1;i这项工作:

#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));
}
#包括
#包括
#包括
long getIORead()
{
文件*j=fopen(“/proc/self/io”,“r”);
如果(j==NULL)
返回-1;
char-buf[256];
while(fgets(buf,250,j)!=NULL)
if(strstr(buf,“读取字节:”)!=NULL)
{
fclose(j);
返回环礁(strchr(buf),)+1;
}
返回-1;
}
int main()
{
很久以前、很久以后都没有签名;
before=getIORead();
{
//代码在这里
}
after=getIORead();
printf(“从磁盘读取的字节数:%d\n”,(int)(之后-之前));
}
它很难看,并且缺乏良好的错误检查,但这演示了如何执行

以下是测试代码读取4095201字节长的文件(很久没有被访问或修改)时的结果:

$/测试
从磁盘读取的字节数:4096000
$/测试
从磁盘读取的字节数:0


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

您的问题没有很好地说明。您是在询问一种方法来确定必须从磁盘读取多少字节才能满足您的读取要求,包括与目录和文件位置相关的元数据?还是只询问数据?或者什么?更确切地说而不是试图让你充分详细地解释你想要什么,这几乎不起作用,而是告诉我们你为什么想要这些信息。这样,我们就可以知道哪些信息会有用,而不必问你大量非常复杂的详细问题。我毫不怀疑你能做到……但我会很高兴看到有人提出解决方案。@DavidSchwartz我只想知道每次读取的数据中有多少来自缓存,有多少来自磁盘。@nbro我不认为有任何内置的解决方案,但人们可以计算出最接近实际目的的数量。我不是这方面的专家,但我会尝试获取
iotop
iostat
strace
的源代码。我认为这些程序使用了解决此任务所需的操作系统调用。答案非常有趣。据我所知,代码预期每次
fopen
后,第一个数据总是从文件中读取,对吗?我注意到,op连续两次打开同一时间文件会导致读取第二个文件的速度更快(就像文件已经被缓存)。这与您的代码如何匹配?我错在哪里了?@4386427此代码假设打开文件不会启动读取(因此
remaining=0
)。同一进程对同一文件的
fopen
后续调用速度更快的原因是,操作系统可能在文件关闭后将某些文件元数据缓存一段时间,希望该进程很快将其重新打开。我的理解(可能完全错误,因为这不是我的工作领域)操作系统将在页面缓存中以只读方式打开文件的所有页面(前提是操作系统没有内存不足)。即使程序终止,文件内容仍将保留在内存中,直到操作系统需要释放内存为止。因此,对同一文件的多次读取(来自同一程序,甚至来自不同程序)不一定会导致读取编号2、3、4等的任何磁盘访问。但是,我可能完全错了:-)@dasblinkenlight bsize始终为0,?Saeid这很奇怪。你能试试看,让我知道它打印的是什么吗?很酷的回答。它让我搜索了网络,我找到了带有一些附加信息的链接:@davidSchwartz.atol(strchr(buf),)+1;始终重新返回0,