Ton*_*vel 2 c c++ boost iostream stl
给定C++ std::istream
输入内存流,是否可以直接将数据从该流写入C文件流(FILE*
)而无需先将数据写入磁盘?
我问的原因是我有一个C接口FILE*
,我希望透明地支持压缩或未压缩的输入文件.
我们的想法是编写一个包装函数来获取输入文件,然后用于boost::iostreams
创建一个过滤流,必要时进行解压缩,然后以某种方式将解压缩的数据转发到C API.
直接的方法是解压缩压缩文件,将解压缩的数据写入磁盘,然后写入fopen
临时文件.我想防止必须创建临时文件.
另一种选择是解压缩内存中的所有数据,然后用于fmemopen
获取FILE*
解压缩的数据.这意味着我可能不得不分配大量数据,我宁愿看一个缓冲的解决方案.这有可能吗?
如果您使用的是GNU系统(Linux,Glibc),则可以使用为解码操作fopencookie
创建FILE *
包装器:
Run Code Online (Sandbox Code Playgroud)FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs);
[...]
fopencookie()函数用于类似于fopen(3)的目的:它打开一个新流并返回一个指向FILE对象的指针,该对象用于对该流进行操作.
cookie参数是指向调用者的cookie结构的指针,该cookie结构将与新流相关联.当标准I/O库调用下面描述的任何钩子函数时,该指针作为第一个参数提供.
mode参数与fopen(3)的用途相同.支持以下模式:r,w,a,r +,w +和a +.有关详细信息,请参见fopen(3).
io_funcs参数是一个结构,它包含四个指向程序员定义的钩子函数的字段,这些函数用于实现此流.结构定义如下
Run Code Online (Sandbox Code Playgroud)typedef struct { cookie_read_function_t *read; cookie_write_function_t *write; cookie_seek_function_t *seek; cookie_close_function_t *close; } cookie_io_functions_t;
[...]
(我不想将整个联机帮助页复制到我的答案中).
基本上你可以这样做:
ssize_t my_read(void *cookie, char *buf, size_t size) {
std::istream *the_stream = static_cast<std::istream*>(cookie);
// insert magic
return bytes_read;
}
cookie_io_functions_t my_functions = {
my_read,
NULL,
NULL,
NULL,
};
...
FILE *wrapped = fopencookie(static_cast<void *>&stream, "rb", my_functions);
Run Code Online (Sandbox Code Playgroud)
在BSD/OSX上,你也同样幸运,因为它funopen
只是一个稍微不同的API来实现完全相同的东西.
如果你想支持Windows,那么,你可怜.