【问题标题】:How to write from a FILE* to a fd?如何从 FILE* 写入 fd?
【发布时间】:2019-03-06 13:35:20
【问题描述】:

我想将FILE* 文件(*.so 库)的内容复制到我将提供给其他函数的文件描述符中。我读过fileno(),但它似乎不能正常工作。 谁能给我一个技巧来做到这一点?

这是我的代码:

int takeFromDisk(char *file){
    int shm_fd;
    shm_fd = open_ramfs(); // Give me a file descriptor to memory
    printf("[+] File Descriptor Shared Memory created!\n");

    FILE *fichier = fopen(file, "r");


    fclose(fichier);
    return(shm_fd);
}

还有我用来获取文件描述符的函数:

int open_ramfs(void) {
    int shm_fd;

    //If we have a kernel < 3.17
    // We need to use the less fancy way
    if (kernel_version() == 0) {
        shm_fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, S_IRWXU);
        if (shm_fd < 0) { //Something went wrong :(
            fprintf(stderr, "[-] Could not open file descriptor\n");
            exit(-1);
        }
    }
    // If we have a kernel >= 3.17
    // We can use the funky style
    else {
        shm_fd = memfd_create(SHM_NAME, 1);
        if (shm_fd < 0) { //Something went wrong :(
            fprintf(stderr, "[- Could not open file descriptor\n");
            exit(-1);
        }
    }
    return shm_fd;
}

我试过的代码:

int c;
while ((c = fgetc(fichier)) != EOF)
{
  write(shm_fd, &c, sizeof(c));
}

【问题讨论】:

  • 1) 可以使用 open() 代替 fopen() 直接获取 FD; 2)如果 fileno() “无法正常工作”,如果您共享您尝试过的代码以及结果是什么,这将有所帮助......
  • @JanKrüger 我想将变量 fichier 的内容复制到我使用 open_ramfs() 创建的文件描述符 shm_fd
  • 你有没有尝试从FILE *write到文件描述符的fread
  • @coco:那你写的什么代码没用?
  • @coco 当然,有很多方法可以做到这一点,有些比其他方法更有效,但我的印象是你在设置基础知识时遇到了麻烦 - 如果是这样的话,有点更多详细信息会有所帮助-例如您尝试过的无效代码。在那之后,最简单(也是效率最低)的方法是循环两个 freadwrite 调用...

标签: c file shared-libraries


【解决方案1】:

你尝试的代码的问题是指针算法的问题。

  • fgetc 将您读取的字节作为值返回,您将其存储到c 中。到目前为止,一切都很好。
  • writefgetc 灵活一点——它一次可以写入多个字节(类似于fread)。所以你不能像你试图做的那样只传递一个整数值 - 它需要一个 pointer 指向你想要写入的字节的内存位置。 &amp;c 是指向 c 使用的内存的指针 - 但等等,这还不是全部......
  • fgetc 返回它在 int 中读取的字节。在所有现代平台上,ints 大于一个字节,因此变量 c 实际上超过一个字节(您将遇到的大多数系统在 int 中有 4 个字节,这也是您的sizeof 将产生的结果,因此您最终会得到一个膨胀因子 4 的文件)。不幸的是,平台的不同之处在于您关心的字节在该变量的内存中的确切位置。在许多使用 &amp;c 的平台上都可以使用,但并非在所有平台上都可以使用。
  • 更好的方法是分配一个固定大小的缓冲区,然后你可以用fread读入它,然后用write把它写到另一个FD,大概像这样(我省略了错误处理和其他细节) :
#define BUFSIZE 4096
char buf[BUFSIZE];
while (1) {
    size_t num_read = fread(&buf, 1, BUFSIZE, fichier);
    if (num_read == 0) break;
    write(shm_fd, &buf, num_read);
}

【讨论】:

  • 值得注意的是,有许多更有效的方法可以将数据从一个文件复制到另一个文件。在 Linux 上,有一个专用的系统函数,称为sendfile。在其他系统上,您可以使用mmap 将其中一个文件映射到虚拟内存以简化操作,虽然效率较低,但仍比使用缓冲区的手动版本好。
猜你喜欢
  • 1970-01-01
  • 2023-01-19
  • 2020-04-18
  • 2013-05-11
  • 1970-01-01
  • 2020-12-06
  • 2015-10-19
  • 2012-12-04
  • 2010-10-07
相关资源
最近更新 更多