Здравствуйте, Аноним, Вы писали:
GZ>>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?
GZ>>
GZ>> std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
GZ>> // данные прочитались успешно?
GZ>>
А>В случае ошибки — исключение.
Я ошибся — в примере должен быть istreambuf_iterator.
Для istream_iterator все понятно. Проверять флаги eof, bad, fail я умею. Как и ловить соответствующие им исключения, для чего предварительно необходимо вызвать exception.
Меня интересует другое — как быть с istreambuf_iterator?
Все оказалось гораздо хуже, чем я думал.
(немного отойду от темы)
Как известно, при чтении файла по достожении его конца (успешном) устанавливаются одновременно 2 флага: eof и fail.
Ситуация такова, что я читаю файл, находящийся на дискете. (Файл не читается где-то на половине).
Так вот, код приведеный ниже читает читабельный кусок файла. Установленные флаги: eof и fail.
т.е. никакой реальной возможно понять правильно ли прочитался файл нет?
Код:
(читаю специально istreambuf_iterator чтобы устанавливались флаги)
Здравствуйте, GregZ, Вы писали:
GZ>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?
А что считать ошибкой?
Такое впечатление, что у istreambuf_iterator ошибок быть не может, только конец файла — следовательно, если есть уверенность, что символов должон быть не меньше n, проверяем размер buf после copy и делаем выводы.
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Здравствуйте, GregZ, Вы писали:
GZ>>Как используя istreambuf_iterator понять, что при чтении произошла ошибка? ГА>А что считать ошибкой?
Например невозможность буфером прочитать данные из устройства ввода (здесь дискета).
ГА>Такое впечатление, что у istreambuf_iterator ошибок быть не может, только конец файла — следовательно, если есть уверенность, что символов должон быть не меньше n, проверяем размер buf после copy и делаем выводы.
А у istream_iterator итератора? Я имел ввиду именно его (см. пример). Скопипастил не оттуда
Ясное деле, что istreambuf_iterator не может устанавливать флаги — он же работает с буфером.
Покопался в стандарте. Оказывается:
Виртуальная функция basic_streambuf<>::underflow (на самом деле выполняющая чтение из устройства ввода) в случае ошибки чтения возвращает EOF, то есть признак невозможности дальнейшего чтения. Какая ошибка — не определяется. Это может быть как конец файла, так и ошибка чтения из файла.
Такое поведение потокового буфера открыло мне глаза на то, что я долго не мог понять: почему флаг eof устанавливается вместе с флагом fail при попытке чтения символа за концом файла.
Я, наивная душа, думал, что флаг fail, предназначен для индикации hardware ошибки чтения (типичный случай самогипноза — я даже предположить не мог что ошибки оборудования никому не нужны). А ведь был в некоторый старых реализациях флаг hard! Теперь меня наконец-то разубедили.
Вывод: в стандартной библиотеке потоков НЕТ возможности определить hardware ошибку чтения. А раз ее нельзя определить чтеним из потока с помощью istreambuf_iterator, то нельзя и с помощью istream_iterator.
Вообще у меня все больше складывается впечатление, что потоки стандартной библиотеки напоминают мамонтов.
Огромные, неповоротливые и неизбежно вымрут.
Здравствуйте, GregZ, Вы писали:
GZ>Вывод: в стандартной библиотеке потоков НЕТ возможности определить hardware ошибку чтения. А раз ее нельзя определить чтеним из потока с помощью istreambuf_iterator, то нельзя и с помощью istream_iterator.
Я думаю, в твоем случае можно средствами ОС узнать размер файла и сравнить с объемом прочитанных данных (если читаешь в двоичном режиме).
GZ>Вообще у меня все больше складывается впечатление, что потоки стандартной библиотеки напоминают мамонтов. GZ>Огромные, неповоротливые и неизбежно вымрут.
Все там будем.
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Я думаю, в твоем случае можно средствами ОС узнать размер файла и сравнить с объемом прочитанных данных (если читаешь в двоичном режиме).
Спасибо, сам уже о таком подумывал.
Только не дело это. Как быть с ситуацией, если поток не поддерживает позиционирование, и узнать размер данных нельзя?