是否有(跨平台)方法从C++ std :: fstream获取C FILE*句柄?
我问的原因是因为我的C++库接受fstreams并且在一个特定的函数中我想使用接受FILE*的C库.
我正在编写一个需要将数据写入现有缓冲区的子程序,我想使用stringstream该类来简化数据的格式化.
最初,我使用以下代码将流的内容复制到缓冲区,但是希望避免这种解决方案,因为它复制了太多数据.
#include <sstream>
#include <algorithm>
void FillBuffer(char* buffer, unsigned int size)
{
std::stringstream message;
message << "Hello" << std::endl;
message << "World!" << std::endl;
std::string messageText(message.str());
std::copy(messageText.begin(), messageText.end(), buffer);
}
Run Code Online (Sandbox Code Playgroud)
这是我发现streambuf::pubsetbuf()方法的时候,简单地重写上面的代码如下.
#include <sstream>
void FillBuffer(char* buffer, unsigned int size)
{
std::stringstream message;
message.rdbuf()->pubsetbuf(buffer, size);
message << "Hello" << std::endl;
message << "World!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这在Visual Studio 2008附带的C++标准库实现下不起作用; buffer保持不变.
我看了一下它的实现,pubsetbuf结果发现它实际上"什么都不做".
virtual _Myt *__CLR_OR_THIS_CALL setbuf(_Elem *, streamsize)
{ // offer buffer to external …Run Code Online (Sandbox Code Playgroud) 我可以使用fopen()将文件指针写入文件.但是我可以创建一个文件指针,这样调用fputc或fprintf之类的函数会写入内存中的指针吗?这方面的一个例子是java中的ByteArrayOutputStream.另外:我可以反向运行它,其中库需要一个文件指针来读取,所以我分配内存,并创建一个新的文件指针,将从该内存位置读取,但当块的大小用完时返回EOF?(如Java中的ByteArrayInputStream).有没有办法在C中这样做?例如:
FILE *p = new_memory_file_pointer();
fprintf(p, "Hello World!\n");
char *data = get_written_stuff(p);
printf("%s", data); //will print Hello World!
Run Code Online (Sandbox Code Playgroud)
&&/||
char s[] = "Hello World!\n";
FILE *p = new_memory_file_pointer_read(s, sizeof(s));
char *buffer = (char *)malloc( 1024*sizeof(char) );
fread((void *)buffer, 1, sizeof(s), p);
printf("%s", buffer); //prints Hello World!
Run Code Online (Sandbox Code Playgroud)
编辑:对于那些多年后阅读这个问题的人,除了接受的答案之外,你应该看一下open_memstream(3),这些行为更像是这些Java类fmemopen.
我在这里用简单的C编写小程序.我需要的是直接在内存中创建一个文件(不写在硬盘上)目前我可以fopen("filename.txt,"wb")用来写入文件.
我知道在linux中你可以使用fmemopen().win32有类似的解决方案吗?
在阅读有关字符串流的GNU文档时,我发现了两个类似的函数,它们执行非常相似的操作:
FILE * fmemopen (void *buf, size_t size, const char *opentype)
FILE * open_memstream (char **ptr, size_t *sizeloc)
Run Code Online (Sandbox Code Playgroud)
从阅读文档,似乎open_memstream应该用于打开输出流和fmemopen输入.让我感到opentype惊讶的是你可以传递给我的论据fmemopen.
linux手册页说明:
如果将buf指定为NULL,则fmemopen()动态分配一个缓冲区大小为bytes的字节.这对于想要将数据写入临时缓冲区然后再次读取的应用程序非常有用.关闭流时,将自动释放缓冲区.请注意,调用者无法获取指向此调用分配的临时缓冲区的指针(但请参阅下面的open_memstream()).
那么,open_memstream如果fmemopen可以处理打开输入/输出流,那将是什么意义?
所有,
我有一个打印到流的程序.我需要在内存中缓冲此流,然后根据需要将每行打印到实际文件中.
由于fprintf()函数调用必须有一个FILE *指针,我需要在内存中使用所述指针寻址空间.我曾使用过该open_memstream()功能,但Windows不支持此功能.
因为malloc()返回一个void *指针,根据需要神奇地转换为必要的指针,我可以使用它作为我的FILE *指针吗?如果是这样,有什么警告?我需要注意空间不足吗?
更新:
在找到了open_memstream()比它应该更难的源之后,看起来他们正在为malloc空间做一个文件流.
既然如此,我已经得到了它们的来源,如果我无法通过mingw获得与Windows交叉编译的工作版本,我将会讨论.
我想:
我知道如何使用dup2和freopen:
......但我不确定第2项?
原因:我想将数据后处理到stdout/err(来自第三方代码),然后将其发送到网络服务器 - 同时让应用程序正常运行.
为什么?...因为现在当我们的应用程序运行时,我们看到关键数据从第三方代码转到stdout(和错误),并且它是一个让用户尝试使用本地日志文件的PITA.我宁愿将"最后N个字节"捕获到环形缓冲区中,对其进行后处理,然后 - 如果用户报告存在问题 - 将其发送到服务器.
为什么要避免文件?...因为这是针对必须在iOS和桌面上运行的代码,并且"不断写入文件"是我想要避免的,因为我不想将它作为文件.另外......我不得不担心维护该文件,主动修剪其大小等.
我想打开一个匿名文件,这就是在Linux下打开文件并取消链接或使用的结果memfd_create,但这些似乎在Windows下都不可用(您可以使删除文件工作,但它的名称不可用)在文件关闭之前似乎不会被删除)。获取不受文件系统中可见内容支持的文件描述符。
windows下有办法实现吗?我最好希望它永远不会出现在文件系统中。
我想要这个的原因是因为我需要FILE*将 a 作为参数发送给需要它的函数(并且我不希望它破坏文件系统)。更改库看起来不是一个可行的选择(此外库也必须在其他操作系统上工作 - 因此它们无论如何都不能依赖于 Windows 特定的抽象)。