3

我有一个代码,我在其中多次访问二进制文件。每次我调用该函数时,它都会打开文件进行读取,并且只读取所需的字节数(n每次都说字节数)。

二进制文件包含时间序列数据,我希望它能够通过循环运行函数调用,每次我调用函数打开同一个文件时,它都需要读出下一个块数据,即,我不希望每次都重置文件指针。有没有办法做到这一点?

该函数如下所示:

int readBinary(float *binImage, int gelements) {
    imageFile = fopen("tmpImageFile", "r");
    if (imageFile == NULL) {
       fprintf(stderr, "Error opening file\n");
       return (1);
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}

在我的主代码中,我想通过一个循环运行它,每次都给它一个binImage大小数组。如果可以避免的话,gelements我宁愿不给它一个大小数组。gelements * nLoop

4

4 回答 4

6

使用静态变量,以便保留文件指针:

int readBinary(float *binImage, int gelements) {
    static FILE *imageFile = NULL;
    if (imageFile == NULL) {
       imageFile = fopen("tmpImageFile", "r");
       if (imageFile == NULL) {
          perror("Error opening file: ");
          return (1);
       }
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}
于 2013-04-20T18:29:11.373 回答
6

快速的经验法则是

如果你适当地划分职能之间的责任,生活会变得更轻松

如果使用静态或全局变量,生活会变得复杂”。

在这种情况下,让readBinary函数既负责管理数据又负责FILE读取数据就太过分了。

请注意,该函数不会关闭句柄。

如果句柄是函数中的局部静态,则无法关闭它。这也意味着该函数将永远被锁定为仅使用“tmpImageFile”(从函数的签名或缺少的文档中无法立即看出这一点)

如果句柄是全局的,则可能会过早关闭它。

请注意,如果您删除“打开文件”职责,则该readBinary函数只是对fread.

处理此问题的最佳方法是完全跳过该readBinary功能。

你说你有一个循环读取数据的调用者。让这个调用者负责打开FILEfread直接在循环中使用并在完成后关闭文件。

现在,这可能会给调用者过多的责任。只需让调用者接受FILE*作为参数并将文件管理责任交给调用者即可。或者调用者的调用者的调用者,这取决于管理文件生命周期的意义所在。

于 2013-04-20T19:07:02.127 回答
3

我会将FILE*as 参数传递给函数:

int readBinary(float *binImage, int gelements, FILE *imageFile) {
    int bytes = fread(binImage, sizeof(float), gelements, imageFile);
    return bytes != -1 ? 0 : 1;
}

我还添加了简单的fread返回值检查并将其转换为您的返回值约定。虽然这个函数看起来很简单,但你可以直接调用fread,除非你想添加错误打印之类的东西。

于 2013-04-20T18:38:51.350 回答
1

您可以将文件指针设为静态并将其初始化为 NULL。然后下一次如果它不是NULL,那么它包含打开的文件。此外,在关闭文件时,请确保再次将其设为 NULL。全局指针也可以这样做

int readBinary(float *binImage, int gelements) {
static imageFile = NULL;
if(imageFile == NULL ) imageFile = fopen("tmpImageFile", "r");
if (imageFile == NULL) {
   fprintf(stderr, "Error opening file\n");
   return (1);
}
fread(binImage, sizeof(float), gelements, imageFile);
return 0;
}
于 2013-04-20T18:28:49.513 回答