Флаг CFile :: osNoBuffer вызывает исключение при записи в файл - PullRequest
2 голосов
/ 24 сентября 2010

(файл создания WINAPI - файл записи WINAPI) Флаг, используемый в winapi (FILE_FLAG_NO_BUFFERING), работает нормально, когда я использую функции winapi для записи файла.

(WINAPI создать файл - CFile - записать файл) В этой ситуации также произошла ошибка, но это произошло из-за отсутствия имени файла в объекте CFile, который был создан из дескриптора файла, полученного из winFi-функции CreateFile.

(CFile создать файл - Cfile - записать файл ) Когда я использую этот флаг (CFile :: osNoBuffer), возникает исключение, когда я пытаюсь что-то записать в файл, сообщая мне, что произошла какая-то нераспознанная ошибка.

что может быть не так?

char chArr [] = "1234567890";
CFile file;
file.Open("c:\\mfc.txt",CFile::modeCreate| CFile::modeNoTruncate| CFile::modeWrite | CFile::osNoBuffer | CFile::osWriteThrough);
file.Write(chArr,sizeof(chArr)); // exception 
file.Flush(); 
file.Close();

Ответы [ 2 ]

4 голосов
/ 24 сентября 2010

См. Это обсуждение буферизации файлов в MSDN.

Открытие файла с флагом CFile::osNoBuffer или передача флага FILE_FLAG_NO_BUFFERING на CreateFile - это совершенно особый способ записи в файл. Это требует, чтобы все буферы, которые вы используете для записи в файл, были выровнены по границе сектора в памяти, а также чтобы вы записали только целое число, кратное размеру сектора. Если вы не предприняли специальных шагов для выравнивания буфера, который вы передаете (чего у вас здесь нет), а также написаны, по крайней мере, например. 512 байт, маловероятно, что он будет работать, если устройство не будет игнорировать ваш флаг. Я думаю, что вы, возможно, не заметили, что WriteFile вернул код ошибки вместо того, чтобы выдавать исключение.

Я бы спросил: почему вы вообще указываете этот флаг? Его использование довольно специализировано, и если вы просто выполняете обычный повседневный файловый ввод-вывод, например, пишете текстовый файл, то вам следует , а не , указать этот флаг. Это, вероятно, замедляет вашу программу, а также делает ее более сложной. Я также рекомендую удалить CFile::osWriteThrough.

Точно так же, как вы знаете: использование FILE_FLAG_NO_BUFFERING почти исключительно для вещей, записывающих огромное количество данных, которые должны поступать непосредственно на диск, таких как приложения для регистрации данных в реальном времени или записи видео. FILE_FLAG_WRITE_THROUGH используется для таких вещей, как файлы журнала базы данных, которые должны сбрасываться после каждой записи для корректной транзакции. Отключение этих кешей и буферов в других случаях обычно замедляет вашу программу.

Вот другое обсуждение кого-то с такой же проблемой (хотя они использовали .NET, а не C ++).

Редактировать: Спасибо за упоминание о размере Daryl.

1 голос
/ 24 сентября 2010

Из обсуждения буферизации файлов MSDN Даг упомянул в своем ответе.

  • Размеры доступа к файлу, включая необязательное смещение файла в структуре OVERLAPPED, если указано, должныдля количества байтов, кратных размеру сектора тома.Например, если размер сектора составляет 512 байт, приложение может запрашивать чтение и запись в 512, 1024, 1536 или 2048 байт, но не в 335, 981 или 7 171 байт.

  • Адреса буфера доступа к файлу для операций чтения и записи должны быть выровнены по секторам, что означает выравнивание по адресам в памяти, кратным размеру сектора тома.В зависимости от диска это требование может быть не выполнено.

В моей системе меняется ...

char chArr[] = "1234567890";

на

char chArr[512] = "1234567890";

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

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