Непоследовательное поведение с fopen в C / C ++ - PullRequest
0 голосов
/ 25 апреля 2011

Я работаю с библиотекой, которая много раз открывает один и тот же файл. Он проверяет заголовок файла, чтобы убедиться, что это правильный формат. Первые 1212 раз он открывает файл, он ведет себя правильно. В 1213-й раз считанные из файла байты отличаются. Кто-нибудь может подсказать, почему это может происходить?

К сожалению, я не могу привести небольшой воспроизводимый пример - и для этого нужно 20 минут. Поэтому мне интересно, есть ли какие-нибудь тонкости fopen, которые я мог бы пропустить, или что-то еще, что может иметь отношение к этому исполнению.

Код ниже. Создается много экземпляров класса, и каждый on имеет initialise (), вызываемый с одинаковым именем файла Первые 1212 раз, на выходе будет:

Expecting: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?

Got: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?

В последний раз я получаю:

Expecting: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?

Got: '   lon       lat    year  

Функция выглядит следующим образом:

class Archive {
private:
FILE* pfile;
<snip>
    bool initialise(char* filename) {

    int i;
    unsigned char* pheader;

    if (pfile) fclose(pfile);
    pfile=fopen(filename,"rb");
    if (!pfile || pfile == NULL ) {
        printf("Could not open %s for input\n",filename);
        return false;
    }

    pheader=new unsigned char[CRU_1901_2002_HEADERSIZE-4];
    if (!pheader) {
        printf("Out of memory\n");
        fclose(pfile);
        pfile=NULL;
        return false;
    }
    ::rewind(pfile);
    fread(pheader,CRU_1901_2002_HEADERSIZE-4,1,pfile);

    printf( "Expecting: '%s'\n", CRU_1901_2002_HEADER);
    for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
        printf( "%c", CRU_1901_2002_HEADER[j]);
    printf( "\nGot: '%s'\n", pheader);
    for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
        printf( "%c", pheader[j]);
    printf( "\n");
    for (i=0;i<CRU_1901_2002_HEADERSIZE-4;i++) {
        if (pheader[i]!=CRU_1901_2002_HEADER[i]) {
            fclose(pfile);
            pfile=NULL;
            delete pheader;
            return false;
        }
    }
    delete pheader;

    ::rewind(pfile);
    fseek(pfile,CRU_1901_2002_HEADERSIZE+CRU_1901_2002_DATA_LENGTH*CRU_1901_2002_NRECORD,SEEK_CUR);
    recno=0;
    iseof=false;

    return true;
}

public:
Archive() {
    pfile=NULL;
}

Archive() {
    if (pfile) fclose(pfile);
}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2011

Оказывается, это слишком много открытых файлов.Изменение программы в другом месте для открытия меньшего количества файлов исправляет ее.

Проверка fread возвращает 1, кроме последнего, где возвращается 0.

Однако я не понимаю, почему fopen возвращаетненулевой указатель файла, когда он не может открыть файл.В тестовом коде возвращается NULL, который затем перехватывается, как и ожидалось.

0 голосов
/ 25 апреля 2011

Вы уверены, что есть данные на 1213-й позиции? или эти данные верны?
Я предлагаю вам смонтировать файл с более чем 1213-ю записями и выполнить тест, чтобы подтвердить, есть ли ошибка чтения или нет в этой позиции.

...