Ответ 1
Я боюсь, что ответ таков: это невозможно с текущим дизайном стандартной библиотеки. Причина в том, что потоковые буфферы полностью скрывают последовательность символов, которыми они управляют. Это делает невозможным прямое копирование байтов из области получения одного буфера потока в область сложения другого.
Если "input" streambuffer будет выставлять свой внутренний буфер, тогда "выходной" streambuffer может просто использовать sputn(in.data(), in.size())
. Или, что более очевидно: если выходной буфер также выставил свой внутренний буфер, можно было бы использовать простой memcpy
для перекоса байтов между ними. Другие библиотеки ввода-вывода работают следующим образом: поток реализации буферов протокола Google, например. Boost IOStreams имеет оптимизированную реализацию для копирования между потоками. В обоих случаях эффективное блочное копирование возможно, потому что эквивалент streambuffer обеспечивает доступ к его промежуточному буферу.
Фактически, потоковым буферистам, по иронии судьбы, даже не нужно иметь буфер: при работе без буферизации каждая запись/запись переходит непосредственно к базовому устройству. Предположительно, это одна из причин, по которой стандартная библиотека не поддерживает интроспекцию. К сожалению, невозможно обеспечить эффективное копирование между потоковыми буферами ввода и вывода. Для копирования на уровне блоков требуется промежуточный буфер, и алгоритм копирования будет работать следующим образом:
- Чтение из входного потокового буфера через
sgetn
в промежуточный буфер. - Запишите из промежуточного буфера в выходной поток буфера через
sputn
. - Перейдите к 1. до тех пор, пока вход не будет исчерпан или не будет сгенерирован вывод выходной бункер-буфера