Russian Qt Forum
Ноябрь 26, 2024, 07:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QFile::open() - как правильно открыть  (Прочитано 43406 раз)
Winstrol
Гость
« Ответ #15 : Август 11, 2009, 20:38 »

Почему QFile::open(QIODevice::WriteOnly) делает Truncate, нафига тогда QIODevice::Truncate?
И как правильно открыть файл на запись без Truncate?
А если б не делал Truncate, то нафига QIODevice::Append?  Подмигивающий
Записан
spectre71
Гость
« Ответ #16 : Август 11, 2009, 22:07 »

А если б не делал Truncate, то нафига QIODevice::Append?  Подмигивающий
QIODevice::Append - делает seek в конец файла!
Записан
Winstrol
Гость
« Ответ #17 : Август 11, 2009, 23:01 »

QIODevice::Append - делает seek в конец файла!
QIODevice в общем случае не умеет seek. Ну и вопрос в силе, QIODevice::Append зачем? 

« Последнее редактирование: Август 11, 2009, 23:08 от Winstrol » Записан
ритт
Гость
« Ответ #18 : Август 12, 2009, 01:31 »

лично я не понимаю подоплёки вопроса.
Записан
Winstrol
Гость
« Ответ #19 : Август 12, 2009, 09:24 »

лично я не понимаю подоплёки вопроса.
Подоплека какого вопроса? Исходного или моего? Если моего, то она такая же, как у исходного. Если какая подоплека и есть, то выставление флага QIODevice::Append по умолчанию при WriteOnly просто неудобно и несовместимо с языком C. Иная подоплека, если и существует, то я ее не вкладывал.

Ну, и кто не знает, seek - семантически не write-only операция для устройств поддерживающих чтение-запись секторами, а не отдельными байтами. Модификация одного байта требует чтения/записи.
Записан
spectre71
Гость
« Ответ #20 : Август 12, 2009, 10:21 »

QIODevice::Append - делает seek в конец файла!
QIODevice в общем случае не умеет seek. Ну и вопрос в силе, QIODevice::Append зачем? 
Цитировать
QIODevice::WriteOnly   0x0002   The device is open for writing.
QIODevice::Append   0x0004   The device is opened in append mode, so that all data is written to the end of the file.
QIODevice::Truncate   0x0008   If possible, the device is truncated before it is opened. All earlier contents of the device are lost.
Записан
alex12
Гость
« Ответ #21 : Август 12, 2009, 10:45 »

Например, файл существует и его размер 100 байт. Открываем файл и записываем 10 байт.

QIODevice::WriteOnly - перепишет первые 10 байт файла, остальные оставит как есть, размер файла будет 100 байт.

QIODevice::WriteOnly|QIODevice::Truncate - обнулит содержимое файла, запишет 10 байт, размер файла будет 10 байт.

QIODevice::WriteOnly|QIODevice::Append - запишет 10 байт в конец файла, размер файла будет 110 байт.

Разве это не так? В чем, собственно, проблема?

« Последнее редактирование: Август 12, 2009, 10:47 от alex12 » Записан
Winstrol
Гость
« Ответ #22 : Август 12, 2009, 10:56 »

QIODevice::WriteOnly   0x0002   The device is open for writing.
QIODevice::Append   0x0004   The device is opened in append mode, so that all data is written to the end of the file.
QIODevice::Truncate   0x0008   If possible, the device is truncated before it is opened. All earlier contents of the device are lost.
Ну ты прям капитан очевидность

Цитировать
QIODevice::WriteOnly - перепишет первые 10 байт файла, остальные оставит как есть, размер файла будет 100 байт.
Это модификация файла(ReadWrite), а не только запись (WriteOnly). В общем случае требуется обычно перемещение к n-му смещению в файле, а это есть операция требующая чтения в буфер, перезапись 10 байт в буфере, запись сектора на диск.
Записан
spectre71
Гость
« Ответ #23 : Август 12, 2009, 11:44 »

Никого не волнует в данном случае физическое представления конкретного QIODevice.
Режимы открытия описаны и если конкретный QIODevice их всех поддерживает, а с QFile это так, то они должны работать как описано!
Записан
alex12
Гость
« Ответ #24 : Август 12, 2009, 11:57 »

Это все к тому, что нельзя открыть QIODevice::WriteOnly без QIODevice::Truncate для физических устройств, поддерживающих только запись? А такие бывают?
Или, например, у пользователя есть права на запись файла, но нет прав на чтение. Строит глазки

А на практике разве такие ситуации встречаются?
Записан
Winstrol
Гость
« Ответ #25 : Август 12, 2009, 12:26 »

А на практике разве такие ситуации встречаются?
Тут важно то, что открытие файла только на запись всегда и везде на практике приводит к truncate. Например, открытие С++ потока ofstream с флагом ios_base::out. Так закреплено в стандарте языка. И данное поведение абсолютно логично для программиста, который руководствуется документацией и стандартами. А придумать аргументы под неверную точку зрения можно, но это не более чем упражнение для ума, не имеющее ни практической, ни теоретической пользы.
Записан
ритт
Гость
« Ответ #26 : Август 12, 2009, 13:31 »

Winstrol, правильно ли я понял, что ты говоришь про избыточность флагов OpenMode?
Записан
spectre71
Гость
« Ответ #27 : Август 12, 2009, 13:34 »

Тут важно то, что открытие файла только на запись всегда и везде на практике приводит к truncate.
Не путай моды fopen с модами QIODevice!
У QIODevice есть для этого режим QIODevice::Truncate, читай доку!
Если бы было как ты говоришь, то QIODevice::Truncate лишний!
Записан
Winstrol
Гость
« Ответ #28 : Август 12, 2009, 14:02 »

Winstrol, правильно ли я понял, что ты говоришь про избыточность флагов OpenMode?
Ну, в некотором смысл можно так сказать. Компактнее всего записываются ключи для fopen.
В комбинации с ключом QIODevice::WriteOnly возможны 2 варианта
  • QIODevice::WriteOnly|QIODevice::Truncate
  • QIODevice::WriteOnly|QIODevice::Append
В комбинации с ключом QIODevice::ReadWrite возможны уже 3 варианта
  • QIODevice::ReadWrite
  • QIODevice::ReadWrite|QIODevice::Truncate
  • QIODevice::ReadWrite|QIODevice::Append

По умолчанию к QIODevice::WriteOnly дописывается QIODevice::Truncate. Т.е. в комбинации с QIODevice::WriteOnly режим QIODevice::Truncate не нужен, но не вообще не нужен (см. QIODevice::ReadWrite). Если бы сделали, чтобы по умолчанию к  QIODevice::WriteOnly дописывался QIODevice::Append, то он бы тогда не был нужен. Одно из двух. Первый вариант с точки зрения логики по умолчанию предпочтительней.
Стандартная библиотека С++ ведет себя аналогично Qt
http://msdn.microsoft.com/en-us/library/44cs32f9.aspx
Цитировать
ios_base::in becomes "r" (open existing file for reading).
ios_base::out or ios_base::out | ios_base::trunc becomes "w" (truncate existing file or create for writing).
ios_base::out | app becomes "a" (open existing file for appending all writes).
ios_base::in | ios_base::out becomes "r+" (open existing file for reading and writing).
ios_base::in | ios_base::out | ios_base::trunc becomes "w+" (truncate existing file or create for reading and writing).
ios_base::in | ios_base::out | ios_base::app becomes "a+" (open existing file for reading and for appending all writes).
« Последнее редактирование: Август 12, 2009, 16:36 от Константин » Записан
ритт
Гость
« Ответ #29 : Август 12, 2009, 16:43 »

без экспрессий, пожалуйста.
мы об одном и том же говорим, но лишь разными словами...
я, например, согласен, что QIODevice::Truncate выглядит лишним, раз уж он всё-равно выставляется при отсутствии QIODevice::Append в режиме записи...но моё согласие/несогласие не имеет абсолютно никакого значения - до 5.0 всё-равно никто не будет пересматривать востребованность данных флагов по причинам совместимости...

а на данный момент у нас имеется проблема - недостаточно полная документация по этим флагам (и, возможно, форсирование Truncate в не совсем правильном месте) - вот её и решаем.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.065 секунд. Запросов: 21.