【问题标题】:how to keep file handle open in c after exiting function退出函数后如何在c中保持文件句柄打开
【发布时间】:2015-02-06 06:30:23
【问题描述】:

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

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

似乎函数打开的文件句柄在函数退出时被关闭 我怎样才能让它保持打开状态?

如果我应该以其他方式这样做,请告诉我

我正在尝试做的示例:

#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;
}

【问题讨论】:

  • 文件将保持打开状态,直到您调用 fclose,但您不会...
  • 为什么有 C++ 标签?也就是说,您传递被复制的指针,对一个副本的更改对原始副本没有影响。研究“参考调用”。
  • 只是一个旁注:你缺少一个 &lt;unistd.h&gt; 包含 sleep()。省略它是不可移植的。
  • 如果你想更新fin,你的函数需要使用指向文件句柄的指针——即使用FILE**,而不是FILE*
  • 正如@RedAlert 所说——你可以让opener()返回一个FILE*(或NULL出错)。

标签: c linux procfile


【解决方案1】:

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;
  }
/...
}

【讨论】:

    【解决方案2】:

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

    if(opener(&fin)) {}
    

    将其作为双指针传递:

    int opener(FILE **fin) {}
    

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

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

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

    【讨论】:

      【解决方案3】:

      C 语言按值传递参数,因此opener 拥有的finmain 拥有的fin 的副本。在 opener 中更改 fin 对 main 的副本没有影响。

      一种解决方案是在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 );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多