LINUX.ORG.RU

Qt, QFile: Разпознать diskfull


0

0

sim-im теряет конфиг, если на диске кончилось место... Старый стирается, новый оказывается пустой (места то нет).

Полез внутрь...
Там примерно следующее:

  QFile f(cfgName + BACKUP_SUFFIX); // use backup file for this ...
    if (!f.open(IO_WriteOnly | IO_Truncate)){
        log(L_ERROR, "Can't create %s", (const char*)f.name().local8Bit());
        return;
    }
    for (unsigned i = 0; i < plugins.size(); i++){
      QCString line = "[";
      // Тут дальше формируется строка 

      f.writeBlock(line, line.length());

     // Ну еще кое-что таким же способом пишется... 

    }
    const int status = f.status();
    const QString errorMessage = f.errorString();
    f.close();
    if (status != IO_Ok) {
        log(L_ERROR, "I/O error during writing to file %s : %s", (const char*)f.name().local8Bit(), (const char*)errorMessage
        return;
    }

Не смотря на то, что директорию с конфигом я засимлинкил на заведомо переполненный раздел, оно почему-то продолжает прибывать в уверенности, что все записалось как следует. И на этом основании уничтожает старый конфиг.

Заменил f.writeBlock(line, line.length()); на

 int size1= f.writeBlock(line, line.length());
        if ( size1 != (int) line.length() ){
           log(L_ERROR, "Error writing file: %s but continue writing...", (const char*)f.name().local8Bit());
           // return;
        } else
        {
          log(L_ERROR, "%i of %i bytes successfuly written in file: %s",size1 , line.length(),(const char*)f.name().local8Bit
        }

Итог: writeBlock свято уверен, что у него все получается...

Попробовал воспроизвести ситуацию в отдельной программе. В отдельной программе: все работает. Как только место заканчивается writeBlock начинает возвращать 0, как ему и положено. Мало того, с другим конфигом, который пишется в симе (их там более одного) все проходит нормально, статус возвращается правильный, и когда место кончилось старый конфиг не стирается.

Кто нибудь с таким сталкивался. Может посоветуете, что делать/ где чего подкрутить/ что читать/ где спросить?

Полный текст функции можно посмотреть тут:
http://svn.berlios.de/viewcvs/sim-im/trunk/sim/plugins.cpp?view=markup
★★★

Правильный ответ

Благодаря товарищу Vadim Suhanov выяснил таки, почему QFile не замечал, что
 пишет на переполненный диск.
Оказывается что 

    const int status = f.status();
    const QString errorMessage = f.errorString();
    f.close();
    if (status != IO_Ok) {
        log(L_ERROR, "I/O error during writing to file %s : %s", (const char*)f.name().local8Bit(), (const char*)errorMessage
        return;
    }

при буферизированном выводе в файл и не догадается, что что-то здесь не так,
ибо сбрасывать на диск он все будет когда ему скажут f.close, а статус ошибки
проверяется до того. (Файл короткий поэтому промежуточных сбросов не
 происходит)

При этом ставить f.close до f.status нельзя, ибо если открыть файл с
 пренудительным небуферизированным выводом, сказав при открытии ему
 IO_Raw, то при каждом write'е он будет честно ругаться, но вот f.close по
какой-то причине статус ему обнулит (типа закрылся успешно).

Посему, правильным, на мой взгляд решением оказалось, перед f.status поставить
f.flush(). Тогда он при буферезированном выводе постигает тот факт, что места
таки нету, а при небуфиризированном, не теряет статус ошибки.

shaplov ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.