c++ use ifstream from memory
Although use of std::istringstream
(sometimes erronously referred to without the leading i
; such a class does exist but is more expensive to construct, as it also sets up an output stream) is very popular, I think it is worth pointing out that this makes—at a minimum—one copy of the actual string (I'd suspect that most implementations create two copies even). Creating any copy can be avoided using a trivial stream buffer:
struct membuf: std::streambuf {
membuf(char* base, std::ptrdiff_t n) {
this->setg(base, base, base + n);
}
};
membuf sbuf(base, n);
std::istream in(&sbuf);
For a small area of memory, the difference may not matter, although the saved allocation can be noticable there, too. For large chunks of memory, it makes a major difference.
If the code that uses the ifstream&
could be changed slightly to use an istream&
then you could easily switch between ifstream
and istringstream
(for reading data from memory):
void read_data(std::istream& in)
{
}
Callers:
std::istringstream in_stream(std::string("hello"));
read_data(in_stream);
std::ifstream in_file("file.txt");
read_data(in_file);
The standard library offers an in-memory istream
that is also writeable: std::stringstream
.
You need to properly abstract your code so that it accepts a generic istream
instead of an ifstream
, construct a stringstream
, populate it with your data and pass that to the function.
For example:
const char* data = "Hello world";
std::stringstream str((std::string(data))); // all the parens are needed,
// google "most vexing parse"
do_something_with_istream(str); // pass stream to your code