【发布时间】:2009-10-13 07:55:07
【问题描述】:
如果我有一个包含文件数据的缓冲区,我如何从中获取文件描述符? 这个问题来源于how to untar file in memory
【问题讨论】:
标签: c
如果我有一个包含文件数据的缓冲区,我如何从中获取文件描述符? 这个问题来源于how to untar file in memory
【问题讨论】:
标签: c
我写了一个简单的例子,如何将文件描述符写入内存区域:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
char buff[]="qwer\nasdf\n";
int main(){
int p[2]; pipe(p);
if( !fork() ){
for( int buffsize=strlen(buff), len=0; buffsize>len; )
len+=write( p[1], buff+len, buffsize-len );
return 0;
}
close(p[1]);
FILE *f = fdopen( p[0], "r" );
char buff[100];
while( fgets(buff,100,f) ){
printf("from child: '%s'\n", buff );
}
puts("");
}
【讨论】:
vmsplice() 可能有用:它避免了使用 for 循环将数据写入管道的需要。
fmemopen()?是的,它是 POSIX 而不是 C,但 pipe() 也是 POSIX,不是吗?
fmemopen() 返回的 FILE* 时,fileno() 将返回 -1。
man fmemopen 说“没有与此函数返回的文件流关联的文件描述符(即,如果调用 fileno(3) 将返回错误在返回的流上)。”但是,它没有说明为什么它不起作用。我有点沮丧,它没有。
在纯 C 中不可能。在纯 C 中,所有文件访问都通过 FILE * 句柄进行,并且只能使用 fopen() 和 freopen() 创建,并且在这两种情况下都必须引用文件路径。由于 C 试图尽可能地具有可移植性,它会将 I/O 限制在可能所有系统都可以以某种方式支持的绝对最低限度。
如果您有可用的 POSIX API(例如 Linux、macOS、iOS、FreeBSD、大多数其他 UNIX 系统),您可以使用fmemopen():
char dataInMemory[] = "This is some data in memory";
FILE * fileDescriptor = fmemopen(dataInMemory, sizeof(dataInMemory), "r");
这是一个真正的文件句柄,可以与所有 C 文件 API 一起使用。它还应该允许搜索,如果您使用管道,这是不可能的,因为管道不支持搜索(您可以模拟前向搜索,但没有办法向后搜索)。
【讨论】:
你不能。与 C++ 不同,文件 I/O 的 C 模型不对扩展开放。
【讨论】: