Скопировать данные из потока в поток без буфера?
В любом случае я могу передать данные из fstream
(файла) в stringstream
(поток в памяти)?
В настоящее время я использую буфер, но для этого требуется удвоить память, потому что вам нужно скопировать данные в буфер, а затем скопировать буфер в строковый поток и до тех пор, пока вы не удалите буфер, данные дублируются в памяти.
std::fstream fWrite(fName,std::ios::binary | std::ios::in | std::ios::out);
fWrite.seekg(0,std::ios::end); //Seek to the end
int fLen = fWrite.tellg(); //Get length of file
fWrite.seekg(0,std::ios::beg); //Seek back to beginning
char* fileBuffer = new char[fLen];
fWrite.read(fileBuffer,fLen);
Write(fileBuffer,fLen); //This writes the buffer to the stringstream
delete fileBuffer;`
Кто-нибудь знает, как я могу написать целый файл в строковый поток без использования промежуточного буфера?
Ответы
Ответ 1
// need to include <algorithm> and <iterator>, and of course <fstream> and <sstream>
ifstream fin("input.txt");
ostringstream sout;
copy(istreambuf_iterator<char>(fin),
istreambuf_iterator<char>(),
ostreambuf_iterator<char>(sout));
Ответ 2
ifstream f(fName);
stringstream s;
if (f) {
s << f.rdbuf();
f.close();
}
Ответ 3
В документации для ostream
есть несколько перегрузок для operator<<
. Один из них принимает streambuf*
и читает все содержимое буфера потока.
Вот пример использования (скомпилированный и протестированный):
#include <exception>
#include <iostream>
#include <fstream>
#include <sstream>
int main ( int, char ** )
try
{
// Will hold file contents.
std::stringstream contents;
// Open the file for the shortest time possible.
{ std::ifstream file("/path/to/file", std::ios::binary);
// Make sure we have something to read.
if ( !file.is_open() ) {
throw (std::exception("Could not open file."));
}
// Copy contents "as efficiently as possible".
contents << file.rdbuf();
}
// Do something "useful" with the file contents.
std::cout << contents.rdbuf();
}
catch ( const std::exception& error )
{
std::cerr << error.what() << std::endl;
return (EXIT_FAILURE);
}
Ответ 4
Единственный способ использования стандартной библиотеки С++ - использовать ostrstream
вместо stringstream
.
Вы можете создать объект ostrstream
со своим собственным буфером char, и тогда он будет владеть буфером (поэтому больше не требуется копирование).
Обратите внимание, что заголовок strstream
устарел (хотя его все еще часть С++ 03, и, скорее всего, он будет всегда доступен для большинства стандартных реализаций библиотек), и вы столкнетесь с большими проблемами, если вы забудьте обнулить нуль данных, предоставленных в ostrstream. Это также относится к операторам потока, например: ostrstreamobject << some_data << std::ends;
(std::ends
nullterminates data).