I'm using a library that has quite a few functions that write to a FILE
but none that seem to conveniently dump the same data to an object in memory. Is there any way to create a FILE
object (or override it) that stores the data in memory instead of writing to disk -- I'd like to avoid the performance hit of opening/writing/reading from files over and over again.
UPDATE: per Rob's suggestion, trying stringstream:
ss.put(c);
std::string myval = ss.str();
printf("Value: %s\n after writing: %i length %lu\n",myval.c_str(),c, myval.length());
But, now trying to get the data (binary) out of the stringstream has me stuck -- how do I grab the binary data I've been adding?
Beside the already mentioned GNU's fmemopen()
, which is known in POSIX as open_memstream, similar solution can be obtained combining mmap()
(using MAP_ANONYMOUS) or any other OS-specific function that returns a file descriptor to a block of memory, and fdopen()
.
EDIT: that was wrong, mmap doesn't create a file descriptor.
The GNU libc has, e.g., fmemopen
which will give you a FILE *
that writes to memory. Try man fmemopen
on your Linux system for details.
I suspect (but do not know for sure) that fmemopen
is a wrapper that orchestrates the mmap
/fdopen
approach mentioned by @Cubbi.
If you are on Mac OS X or iOS you don't have access to fmemopen. I've open sourced a solution here:
http://jverkoey.github.com/fmemopen/
If you have the option of modifying your library, you could use C++ streams instead of C FILE streams.
If your old library function looked like this:
void SomeFun(int this, int that, FILE* logger) {
... other code ...
fprintf(logger, "%d, %d\n", this, that);
fputs("Warning Message!", logger);
char c = '\n';
fputc(c, logger);
}
you might replace that code with:
void SomeFun(int this, int that, std::ostream& logger) {
... other code ...
logger << this << ", " << that << "\n";
// or: logger << boost::format("%d %d\n") %this %that;
logger << "Warning Message!";
char c = '\n';
logger.put(c);
// or: logger << c;
}
Then, in your non-library code, do something like:
#include <sstream>
std::stringstream logStream;
SomeFun(42, 56, logStream);
DisplayCStringOnGui(logStream.str().c_str());
Consider mounting a tmpfs
and have the application write to it. Of course this is *nix only.