Как получить файловый дескриптор буфера в памяти?

Если у меня есть буфер, который содержит данные файла, как я могу получить дескриптор файла из него? Это вопрос о том, как распаковать файл в памяти

14 c
13.10.2009 07:55:07
3 ОТВЕТА
РЕШЕНИЕ

Я написал простой пример, как сделать filedescriptor в области памяти:

#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("");
}
13
13.10.2009 09:05:45
Ницца. В качестве небольшого улучшения вы можете использовать fcntl(fd, F_SETPIPE_SZ, ...)для увеличения размера буфера канала. Кредит msandiford для этого.
D.W. 19.06.2015 00:41:26
В Linux это vmsplice()может быть полезно: это устраняет необходимость в цикле for для записи данных в канал.
D.W. 19.06.2015 00:59:28
Это довольно крутое решение, но если вам нужно иметь возможность делать больше, чем просто читать с fd (т.е. искать), то это не сработает. Вы не можете искать на трубе (по крайней мере, на платформах, которые я использую).
John Bowers 9.06.2016 19:37:04
Почему ты не выбрал fmemopen()? Да, это POSIX, а не C, но pipe()также POSIX, не так ли?
Mecki 17.01.2019 16:47:13
@Mecki появляется из справочных страниц, которые fileno()будут возвращаться -1при вызове с FILE*возвращенным из fmemopen().
tekknolagi 29.07.2019 18:01:41

Ты не можешь В отличие от C ++, модель C файлового ввода / вывода не открыта для расширения.

0
13.10.2009 08:06:51
fmemopen может возвращать FILE * из буфера, но fileno (fmemopen (...)) возвращает -1. У меня появилась другая идея: создать содержимое канала и буфера подачи в file_pipes [1] с помощью функции write (), и мы можем посмотреть file_pipes [0] как файловый дескриптор этого буфера. Но когда я практикую это, функция write () просто блокируется. Буфер ядра в pipe не достаточно большой? Спасибо
solotim 13.10.2009 08:12:32
Это POSIX, IIRC. Не C, как вы пометили свой вопрос. Т.е. это не будет работать на Windows.
MSalters 13.10.2009 08:39:00

Невозможно на простом C. На простом C весь доступ к файлу происходит через FILE *дескрипторы, и они могут быть созданы только с fopen()и, freopen()и в обоих случаях должны ссылаться на путь к файлу. Поскольку C пытается быть максимально переносимым, он ограничивает ввод-вывод абсолютным минимальным значением, которое, возможно, все системы могут каким-либо образом поддерживать.

Если у вас есть POSIX API (например, Linux, macOS, iOS, FreeBSD, большинство других систем UNIX), вы можете использовать fmemopen():

char dataInMemory[] = "This is some data in memory";
FILE * fileDescriptor = fmemopen(dataInMemory, sizeof(dataInMemory), "r");

Это настоящий дескриптор файла, который можно использовать со всеми API-интерфейсами C-файлов. Также следует разрешить поиск, что невозможно, если вы работаете с трубами, поскольку каналы не поддерживают поиск (вы можете подражать поиску вперед, но нет способа когда-либо искать назад).

3
17.01.2019 16:54:54