сколько байтов на самом деле написано ostream :: write?

предположим, что я посылаю большой буфер для ostream :: write, но только его начальная часть фактически успешно написана, а остальное не написано

int main()
{
   std::vector buf(64 * 1000 * 1000, 'a');//64 mbytes of data
   std::ofstream file("out.txt");
   file.write(&buf[0], buf.size());//try to write 64 mbytes
   if(file.bad()) {
    //but suppose only 10 megabyte were available on disk
    //how many were actually written to file???
   }
   return 0;
}

какая функция ostream может сказать мне, сколько байтов было написано?

4
добавлено отредактировано
Просмотры: 2
nl ja de
Не связано с вашим вопросом: вы не должны использовать void main() , и у вас есть порядок аргументов для vector :: vector() назад.
добавлено автор Robᵩ, источник
спасибо @ Robᵩ фиксированный код, чтобы сосредоточить усилия на вопросе.
добавлено автор Aviad Rozenhek, источник

2 ответы

Вы можете использовать .tellp() для знать позицию вывода в потоке для вычисления количества байтов, записанных как:

size_t before = file.tellp(); //current pos

if(file.write(&buf[0], buf.size())) //enter the if-block if write fails.
{
  //compute the difference
  size_t numberOfBytesWritten = file.tellp() - before;
}

Обратите внимание: нет гарантии, что numberOfBytesWritten действительно количество байтов, записанных в файл, но должно работать в большинстве случаев, поскольку у нас нет надежного способа чтобы получить фактическое количество байтов, записанных в файл.

6
добавлено
@AProgrammer: Обновлено.
добавлено автор Nawaz, источник
@AviadRozenhek: он не является надежным даже при записи в файл. но .tellp() - это все, что мы получаем на C ++.
добавлено автор Nawaz, источник
@AviadRozenhek: Я понятия не имею, что делать flush() , после того, как write завершится с ошибкой.
добавлено автор Nawaz, источник
После того, как write завершится сбой, все дальнейшие операции с потоком не будут выполняться до тех пор, пока ошибка не будет очищена. Включая tellp , который должен возвращать -1, если предыдущая операция завершилась неудачно.
добавлено автор James Kanze, источник
Это сделало бы хороший комментарий или редактирование, а не ответ.
добавлено автор Robᵩ, источник
Как это отвечает на вопрос, который стоит написать?
добавлено автор AProgrammer, источник
@AProgrammer - это ответ по-прежнему действителен, если ostream пишет в сокет, а не в файл?
добавлено автор Aviad Rozenhek, источник
@Nawaz проблема [я думаю], что со многими реализациями ostream в качестве оболочки для сокета tellp() возвращает -1 всегда ...
добавлено автор Aviad Rozenhek, источник
@Nawaz использует flush() в любом случае?
добавлено автор Aviad Rozenhek, источник

Я не вижу эквивалента gcount() . Написание непосредственно на streambuf (с помощью sputn() ) даст вам указание, но в вашем запросе есть фундаментальная проблема: запись буферизована, а обнаружение отказа может быть отложено до эффективного написания (сброс или close), и нет способа получить доступ к тому, что на самом деле написала ОС.

2
добавлено
На самом деле единственным решением является выяснить размер файла (из системы, используя системные вызовы) перед записью, затем после записи закрыть файл и использовать тот же системный вызов, чтобы найти новый размер. \
добавлено автор James Kanze, источник