проверки ошибок потоков ввода-вывода

BagaBaga
Дата: 02.12.2014 21:20:47
Есть вот такой код

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());

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

Вопрос: как в таком случае лучше всего проверять ошибки ввода-вывода? Речь не идёт о ситуации порождения исключения. Вполне возможна ситуация, когда скачался кусок файла из-за недостаточной производительности подсистемы ввода-вывода (для усиления - пусть это будет дискета). В "обычной ситуации" "недосчитывание" можно посмостреть чере fail-bit. Кто как поступает?
White Owl
Дата: 03.12.2014 08:02:50
fp=fopen();
while(! feof(fp) ) {
   fread( fp, .... );
}
fclose();

И никаких проблем.
BagaBaga
Дата: 03.12.2014 09:38:01
Не совсем :) Это скорее сишный код. Точно не STL :)
И отлов ошибок (прочитал меньше, чем должен был) просто переносится в цикл - на вызов fread :))
mayton
Дата: 03.12.2014 09:54:13
MasterZiv
Дата: 03.12.2014 11:03:23
BagaBaga
Вопрос: как в таком случае лучше всего проверять ошибки ввода-вывода? Речь не идёт о ситуации порождения исключения. Вполне возможна ситуация, когда скачался кусок файла из-за недостаточной производительности подсистемы ввода-вывода (для усиления - пусть это будет дискета). В "обычной ситуации" "недосчитывание" можно посмостреть чере fail-bit. Кто как поступает?


А кто мешает проверить этот fail-bit в этом коде после операции ?
BagaBaga
Дата: 03.12.2014 22:14:29
MasterZiv,
да ни кто в общем-то не мешает. Что-то вроде
t.fail()

Просто при чтении "по привычке" в С-стиле посимвольно всегда можно повторить чтение (в одном и том же цикле). А здесь придётся как-то дочитывать и делать append(). Вот и интересно, кто как заморачивается, если заморачивается.
MasterZiv
Дата: 03.12.2014 23:05:35
BagaBaga,

я не понимаю, что там можно проверять и что дочитывать, если эта конструкция читает весь файл в строку.
BagaBaga
Дата: 04.12.2014 00:34:30
MasterZiv,
эта конструкция должна читать весь файл в строку, но не гарантирует этого.

Приведу простой (невыдуманный) пример:

Требовалось распарсить ней достаточно большой файл. Читался он в С-стиле с помощью fopen-fclose-fread посимвольно. Проблема была в том, что в таком стиле он парсился достаточно долго. Для ускорения этого процесса сначала стали заводить локальный буфер, в который читался сразу блок, а затем анализ проводился посимвольно (с подкачкой данных в буфер, если финальный токен не оказывался в буфере). Но поддерживать буфер самому посчитали некомильфо, тем более, в потоки ввода-вывода уже встроена буферизация. Решили попробовать "буферизацию от профи", и делали "в лоб" типа while(cin >> ch){}. Такой подход принёс неожиданный сюрприз: хоть "всё и ускорилось", часть файлов, находившихся на NFS или при интенсивной I/O, новой версией парситься перестало. Получалось: когда обработка опустошала буфер cin, если до следующего чтения из cin он не успевал "пополниться", происходил выход из цикла (с флагом cin.fail() ). В результате решили читать не посимвольно, а в string (кусками, чтобы не пытаться запихнуть в память несколько гигов). Опустошить буфер при этом стало проблематично ( мы сделали это в нескольких специальных случаях :), но и на эту "экзотику" ввели проверку и несколько попыток на "дочитывание" (и последующее str.append(rest)). В результате получили 1. выигрыш по скорости по сравнению с небуферизированным чтением 2. уход от ручного управления буферами. По скорости, что интересно, получилось чуть медленнее чистого С с "ручным" буфером.

ЗЫ
Понятно, что можно было написать свой класс, который прятал бы исходный С-буфер и процесс его подкачки. Но решение cin + string оказалось достаточно простым и прозрачным.

ЗЗЫ
Синхронизацию потоков с stdin и stdout отключили сразу, так что из-за этого тормозить не может
White Owl
Дата: 04.12.2014 04:17:12
BagaBaga,

Вот что религия с людьми делает.
Нормальный человек возьмет и сделает задачу на том, на чем удобно.
А фанатик stl'я будет упрямо ковырять stl.
Dima T
Дата: 04.12.2014 06:27:16
BagaBaga
Но поддерживать буфер самому посчитали некомильфо

отображение в память средствами ОС не пробовали?