[英]How to write to a memory buffer with a FILE*?
Is there any way to create a memory buffer as a FILE*.有没有办法将内存缓冲区创建为 FILE*. In TiXml it can print the xml to a FILE* but i cant seem to make it print to a memory buffer.在 TiXml 中,它可以将 xml 打印到 FILE*,但我似乎无法将其打印到内存缓冲区。
有一个POSIX的方式来使用内存作为FILE
描述: fmemopen
或open_memstream
,根据语义你想要的: fmemopen和open_memstream的区别
I guess the proper answer is that by Kevin.我想正确的答案是凯文。 But here is a hack to do it with FILE *.但是这里有一个技巧可以用 FILE * 来做到这一点。 Note that if the buffer size (here 100000) is too small then you lose data, as it is written out when the buffer is flushed.请注意,如果缓冲区大小(此处为 100000)太小,则会丢失数据,因为在刷新缓冲区时会写出数据。 Also, if the program calls fflush() you lose the data.此外,如果程序调用 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]);
}
}
fmemopen 可以从缓冲区创建 FILE,这对您有意义吗?
I wrote a simple example how i would create an in-memory FILE:我写了一个简单的例子,我将如何创建一个内存文件:
#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("");
}
C++ basic_streambuf
inheritance C++ basic_streambuf
继承
In C++, you should avoid FILE*
if you can.在 C++ 中,如果可以,您应该避免使用FILE*
。
Using only the C++ stdlib, it is possible to make a single interface that transparently uses file or memory IO.仅使用 C++ stdlib,就可以制作一个透明地使用文件或内存 IO 的接口。
This uses techniques mentioned at: Setting the internal buffer used by a standard stream (pubsetbuf)这使用了以下提到的技术: 设置标准流使用的内部缓冲区 (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);
}
}
Unfortunately, it does not seem possible to interchange FILE*
and fstream
: Getting a FILE* from a std::fstream不幸的是,似乎不可能互换FILE*
和fstream
: 从 std::fstream 获取 FILE*
You could use the CStr method of TiXMLPrinter which the documentation states:您可以使用文档说明的TiXMLPrinter的CStr方法:
The TiXmlPrinter is useful when you need to:当您需要执行以下操作时,TiXmlPrinter 很有用:
- Print to memory (especially in non-STL mode)打印到内存(尤其是在非 STL 模式下)
- Control formatting (line endings, etc.)控制格式(行尾等)
https://github.com/Snaipe/fmem is a wrapper for different platform/version specific implementations of memory streams https://github.com/Snaipe/fmem是针对不同平台/版本的内存流特定实现的包装器
It tries in sequence the following implementations:它依次尝试以下实现:
When no other mean is available, fmem falls back to tmpfile()当没有其他方法可用时,fmem 回退到 tmpfile()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.