如何使用FILE *写入内存缓冲区?

时间:2009-02-12 00:39:45

标签: c++ c

有没有办法将内存缓冲区创建为FILE *。在TiXml中,它可以将xml打印到FILE *但我似乎无法将其打印到内存缓冲区。

7 个答案:

答案 0 :(得分:62)

有一种POSIX方式可以将内存用作FILE描述符:fmemopenopen_memstream,具体取决于您想要的语义:Difference between fmemopen and open_memstream

答案 1 :(得分:21)

我想正确的答案是凯文。但这是用文件*做的黑客攻击。请注意,如果缓冲区大小(此处为100000)太小,则会丢失数据,因为在刷新缓冲区时会将其写出。此外,如果程序调用fflush(),则会丢失数据。

#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]);
    }
}

答案 2 :(得分:9)

fmemopen可以从缓冲区创建FILE,对你有意义吗?

答案 3 :(得分:4)

我写了一个简单的例子,我将如何创建内存中的文件:

#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("");
}

答案 4 :(得分:2)

您可以使用文档声明的CStr TiXMLPrinter方法:

  

TiXmlPrinter对您有用   需要:

     
      
  1. 打印到内存(特别是在非STL模式下)
  2.   
  3. 控制格式(行结尾等)
  4.   

答案 5 :(得分:1)

C ++ basic_streambuf继承

在C ++中,如果可以的话,你应该避免使用FILE*

仅使用C ++ stdlib,可以创建一个透明地使用文件或内存IO的单个接口。

这使用了Setting the internal buffer used by a standard stream (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);
    }
}

不幸的是,似乎无法交换FILE*fstreamGetting a FILE* from a std::fstream

答案 6 :(得分:0)

https://github.com/Snaipe/fmem 是针对不同平台/版本特定内存流实现的包装器

它依次尝试以下实现:

  • open_memstream。
  • fopencookie,具有不断增长的动态缓冲区。
  • funopen,具有不断增长的动态缓冲区。
  • WinAPI 临时内存支持文件。

当没有其他方法可用时,fmem 回退到 tmpfile()