【问题标题】:How to get file descriptor of buffer in memory?如何获取内存中缓冲区的文件描述符?
【发布时间】:2009-10-13 07:55:07
【问题描述】:

如果我有一个包含文件数据的缓冲区,我如何从中获取文件描述符? 这个问题来源于how to untar file in memory

【问题讨论】:

    标签: c


    【解决方案1】:

    我写了一个简单的例子,如何将文件描述符写入内存区域:

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

    【讨论】:

    • 在 Linux 上,vmsplice() 可能有用:它避免了使用 for 循环将数据写入管道的需要。
    • 这是一个非常棒的解决方案,但如果您需要能够做的不仅仅是从 fd 中读取(即 seek),那么这将不起作用。你不能在管道上寻找(至少不能在我使用的平台上)。
    • 为什么不选择fmemopen()?是的,它是 POSIX 而不是 C,但 pipe() 也是 POSIX,不是吗?
    • @Mecki 从手册页中可以看出,当调用从 fmemopen() 返回的 FILE* 时,fileno() 将返回 -1
    • 只是为了引用@tekknolagi 的评论,man fmemopen 说“没有与此函数返回的文件流关联的文件描述符(即,如果调用 fileno(3) 将返回错误在返回的流上)。”但是,它没有说明为什么它不起作用。我有点沮丧,它没有。
    【解决方案2】:

    在纯 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 一起使用。它还应该允许搜索,如果您使用管道,这是不可能的,因为管道不支持搜索(您可以模拟前向搜索,但没有办法向后搜索)。

    【讨论】:

      【解决方案3】:

      你不能。与 C++ 不同,文件 I/O 的 C 模型不对扩展开放。

      【讨论】:

      • fmemopen 可以从缓冲区返回 FILE*,但 fileno(fmemopen(...)) 返回 -1。我有另一个想法:通过 write() 函数创建管道并将缓冲区内容提供给 file_pipes[1],我们可以将 file_pipes[0] 视为该缓冲区的文件描述符。但是当我练习这个时, write() 函数就被阻塞了。管道的内核缓冲区不够大吗?谢谢
      • 这是 POSIX,IIRC。不是 C,这是您标记问题的方式。 IE。它不能在 Windows 上运行。
      猜你喜欢
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 2010-12-03
      相关资源
      最近更新 更多