c++ - romualfons - ¿Cómo escribir en un búfer de memoria con un ARCHIVO*?
romuald seo (6)
¿Hay alguna forma de crear un búfer de memoria como un ARCHIVO *? En TiXml puede imprimir el xml a un ARCHIVO * pero no puedo hacer que se imprima en un búfer de memoria.
Creo que la respuesta correcta es la de Kevin. Pero aquí hay un truco para hacerlo con FILE *. Tenga en cuenta que si el tamaño del búfer (aquí 100000) es demasiado pequeño, perderá datos, ya que se escribe cuando se vacía el búfer. Además, si el programa llama a fflush () pierde los datos.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *f = fopen("/dev/null", "w");
int i;
int written = 0;
char *buf = malloc(100000);
setbuffer(f, buf, 100000);
for (i = 0; i < 1000; i++)
{
written += fprintf(f, "Number %d/n", i);
}
for (i = 0; i < written; i++) {
printf("%c", buf[i]);
}
}
Escribí un ejemplo simple de cómo crearía un ARCHIVO en memoria:
#include <unistd.h>
#include <stdio.h>
int main(){
int p[2]; pipe(p); FILE *f = fdopen( p[1], "w" );
if( !fork() ){
fprintf( f, "working" );
return 0;
}
fclose(f); close(p[1]);
char buff[100]; int len;
while( (len=read(p[0], buff, 100))>0 )
printf(" from child: ''%*s''", len, buff );
puts("");
}
Puede usar el método TiXMLPrinter de TiXMLPrinter que TiXMLPrinter la documentación:
TiXmlPrinter es útil cuando necesita:
- Imprimir en la memoria (especialmente en modo no STL)
- Formato de control (terminaciones de línea, etc.)
fmemopen puede crear un ARCHIVO desde el búfer, ¿tiene sentido para usted?
C ++ basic_streambuf
En C ++, debe evitar FILE*
si puede.
Al utilizar solo C ++ stdlib, es posible crear una única interfaz que utilice de forma transparente IO de archivos o memoria.
Esto usa las técnicas mencionadas en: Configuración del buffer interno utilizado por una secuencia estándar (pubsetbuf)
#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <ostream>
#include <sstream>
/* This can write either to files or memory. */
void write(std::ostream& os) {
os << "abc";
}
template <typename char_type>
struct ostreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> > {
ostreambuf(char_type* buffer, std::streamsize bufferLength) {
this->setp(buffer, buffer + bufferLength);
}
};
int main() {
/* To memory, in our own externally supplied buffer. */
{
char c[3];
ostreambuf<char> buf(c, sizeof(c));
std::ostream s(&buf);
write(s);
assert(memcmp(c, "abc", sizeof(c)) == 0);
}
/* To memory, but in a hidden buffer. */
{
std::stringstream s;
write(s);
assert(s.str() == "abc");
}
/* To file. */
{
std::ofstream s("a.tmp");
write(s);
s.close();
}
/* I think this is implementation defined.
* pusetbuf calls basic_filebuf::setbuf(). */
{
char c[3];
std::ofstream s;
s.rdbuf()->pubsetbuf(c, sizeof c);
write(s);
s.close();
//assert(memcmp(c, "abc", sizeof(c)) == 0);
}
}
Desafortunadamente, no parece posible intercambiar FILE*
y fstream
: Obtener un FILE * desde un std :: fstream
Existe una forma POSIX de utilizar la memoria como un descriptor FILE
: fmemopen
o open_memstream
, dependiendo de la semántica que desee: Diferencia entre fmemopen y open_memstream