0

我正在尝试定期读取 proc 文件 /proc/stat ,但我想避免每次要访问它时都必须打开和关闭 proc 文件。

我想以某种 init 函数打开文件,然后继续在其他函数中使用它,然后再关闭它。

当函数退出时,函数打开的文件句柄似乎关闭了如何保持打开状态?

请让我知道我是否应该以其他方式这样做

我正在尝试做的示例:

#include <stdio.h>

int printer(FILE* fin)
{
  /* I am getting fin as NULL */
  if(!fin)
    return 1;

  char buf[16*1024];
  rewind(fin);
  size_t sz = fread(buf, 1, sizeof(buf), fin);
  if (sz) {
    buf[sz]=0;
    printf(buf);
  }

  return 0;
}

int opener(FILE *fin)
{
  fin = fopen("/proc/stat", "r");
  if (!fin) {
    perror("fopen");
    return 1;
  }

  return 0;
}

int main() {
  FILE *fin;
  /* 
   * I know it works if I open the file handle in here instead of
   * in another function but I want to avoid this
   */
  if(opener(fin)) 
  {
      printf("ERROR1\n");
      return 0;
  }

  while(1) {
    if(printer(fin))
    {   
      printf("ERROR2\n");
      break;
    }   
    sleep(1);
  }
  return 0;
}
4

3 回答 3

2

c 中的函数是按值传递的。因此,当您将文件句柄传递给函数时,它会收到该句柄的副本并将在本地更新它。如果您希望这些更新传播给您的调用者,您需要传递文件句柄指针。所以你的打开看起来像:

int opener(FILE **fin)
{
  *fin = fopen("/proc/stat", "r");
  if (!(*fin)) {
    perror("fopen");
    return 1;
  }

  return 0;
}

你会这样称呼它:

int main() {
  FILE *fin;
  /* 
   * I know it works if I open the file handle in here instead of
   * in another function but I want to avoid this
   */
  if(opener(&fin)) 
  {
      printf("ERROR1\n");
      return 0;
  }
/...
}
于 2015-02-05T22:26:38.817 回答
0

您需要将指针的引用传递给 fin 以便将其保留在 main 中。

if(opener(&fin)) {}

将其作为双指针传递:

int opener(FILE **fin) {}

并将其与取消引用一起使用

*fin = fopen("/proc/stat", "r");

否则每次调用子函数时都会启动它。

于 2015-02-05T22:28:07.307 回答
0

C 语言按值传递参数,因此finthat openerhas 是 that has 的fin副本main。更改finopenermain 的副本没有影响。

一种解决方案是使用临时文件指针opener,然后返回该指针。要指示错误,请返回 NULL。

FILE *opener( char *name )
{
    FILE *temp = fopen( name, "r" );
    if ( !temp )
    {
        perror( "fopen" );
        return( NULL );
    }
    return( temp );
}

int main( void )
{
    FILE *fin = opener( "/proc/stat" );

    if ( !fin )
        printf( "failed\n" );
    else
        printf( "fin=%p\n", fin );
}
于 2015-02-05T22:30:23.743 回答