Задержка открытых файлов приводит к «слишком много открытых файлов» - PullRequest
1 голос
/ 24 января 2012

У меня есть код, использующий повышение для отображения содержимого каталога, итерации по каждому файлу и выполнения некоторых операций обработки данных. Результаты печатаются в выходной файл ('histFile'). После обработки ~ 2555 файлов выдается ошибка:

boost :: filesystem :: directory_iterator :: construct: Слишком много открытых файлов: "/Users/.../.../.../directory_with_files"

Мой код:

for(int i = 0; i < 10000; i++) {
    FILE *histFile;
    string outputFileName = "somename";
    bool ifRet = initFile(histFile, outputFileName.c_str(), "a");   // 1
    fclose(histFile);                                               // 2
}

Если я закомментирую последние две строки выше ('1' и '2'), код завершится нормально. Таким образом, кажется, что копии histFile остаются открытыми, но я не понимаю, как! Это оперативная часть метода:

bool initFile(FILE *&ofFile, const char *fileName, const char *openType, int overwriteOption) {

if(overwriteOption < 0 || overwriteOption > 2) {
    fprintf(stderr, "ERROR: ToolBox - initFile() : unknown 'overwriteOption' (%d), setting to (0)!\n", overwriteOption);
}

// Read-Only
if(openType == "r") {
    if(ofFile = fopen(fileName, "r")) { return true; }
    fprintf(stderr, "ERROR: Could not open file (%s)!\n", fileName);
    return false;
}

// Appending:
if(openType == "a" || openType == "a+") {
    // Check if file already exists
    if(!fopen(fileName, "r")){
        fprintf(stderr, "ERROR: (%s) File does not Exist, cannot append!\n", fileName);
        return false;
    }   
    if(ofFile = fopen(fileName, openType)) { return true; }     
}

// Writing:
//    if file already exists
if(FILE *temp = fopen(fileName, "r")){
    if(overwriteOption == 2) {
        fprintf(stderr, "ERROR: (%s) File Exists!\n", fileName);
        return false;
    }
    if(overwriteOption == 1) {

    }
    if(overwriteOption == 0) {
        char backupFileName[TB_CHARLIMIT], backupPrefix[TB_CHARLIMIT];
        strcpy(backupFileName, fileName);                                  // copy filename
        // create a prefix w/ format '<YYYYMMDD>BACKUP_'
        DateTime now;
        sprintf(backupPrefix, "%s", now.getDateStr().c_str());
        strcat(backupPrefix, "BACKUP_");
        // add to copied filename, and move file
        strcpy(backupFileName, prependFileName(backupFileName, backupPrefix));
        moveFile(fileName, backupFileName);
    }   
    fclose(temp);
} 

if(ofFile = fopen(fileName, openType)) { return true; }


// Default: Return error and false 
fprintf(stderr, "ERROR: Could not open file (%s)!\n", fileName);
return false;
} 

Что-то не так с указателями / ссылками? Любая помощь с благодарностью!

1 Ответ

4 голосов
/ 24 января 2012

Вы пропускаете дескриптор этого фрагмента кода, когда тестируете, существует ли файл уже:

// Appending:
if(openType == "a" || openType == "a+") {
    // Check if file already exists

    if(!fopen(fileName, "r")){     //  <-- the FILE* opened here is leaked

        fprintf(stderr, "ERROR: (%s) File does not Exist, cannot append!\n", fileName);
        return false;
    }   
    if(ofFile = fopen(fileName, openType)) { return true; }     
}

Есть ли причина, чтобы сделать эту проверку? Почему бы просто не позволить файлу быть создан, если он еще не существует?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...