Объединить два файловых указателя - PullRequest
0 голосов
/ 25 октября 2018

Я ищу функцию FILE * join (FILE * a, FILE * b), которая эквивалентна popen("cat a b", "r");.То есть вызов join должен создать новый указатель файла, который содержит весь файл a, тогда весь файл b.

Предпочтительно join должен быть ленивым, чтобы файл b былне читается, пока не будет использован весь файл a.

Ответы [ 4 ]

0 голосов
/ 25 октября 2018

Вот моя функция соединения, см. Ответ Антти Хаапалы о проблемах совместимости.

typedef struct {
  FILE * a;
  FILE * b;
} myCookie;

ssize_t join_read(myCookie * cookie, char *buf, size_t size) {
  size_t s = fread(buf, 1, size, cookie->a);

  if (s < size)
    s += fread(buf+s, 1, size-s, cookie->b);

  return s;
}

int join_close(myCookie * cookie) {
  return fclose(cookie->a) | fclose(cookie->b);
}

FILE * join (FILE * a, FILE * b) {
  myCookie * cookie = malloc(sizeof(myCookie));
  cookie->a = a;
  cookie->b = b;
  return fopencookie(cookie, "r", (cookie_io_functions_t)
      { join_read
      , NULL
      , NULL
      , join_close });
}

Поскольку это уже специфично для Linux, мы также можем определить функцию:

FILE * empty () {
  return fopen("/dev/null", "r");
}

Теперь файловые указатели образуют моноид под join и empty!

0 голосов
/ 25 октября 2018

Вы не можете создать переносную функцию для этого.Это возможно сделать с fopencookie с Linux / Glibc или funopen на BSD.См .: Возможно ли использовать функции, которые действуют на FILE * в пользовательских структурах? Я не знаю ни одного метода для этого в Windows.

Вам просто нужно предоставить методдля чтения, которое просто попыталось бы прочитать заданное количество байтов из первого дескриптора файла, который до сих пор не имеет условия конца файла.

0 голосов
/ 25 октября 2018

Не думаю, что вы могли бы: по крайней мере, не создавая временный файл и не оборачивая результат в FILE*, который позволяет вам использовать "нормальные" функции доступа к файлам, такие как fread() и т. Д.

Логика достаточно проста: чтение с a до конца файла, затем чтение с b, но вы не можете "попасть внутрь" процедур обработки FILE* (по крайней мере, впортативный способ, согласно ответу Антти ), чтобы заставить их переключаться с одного файла на другой.

Вы могли бы написать функцию (ы), которая заменила специфические функции обработки файлов, которые принимают два FILE* аргумента, например, вы можете определить fread2(void *ptr, size_t size, size_t nmemb, FILE *stream1, FILE* stream2), который принимает два потока, и читать из одного до тех пор, пока он не будет исчерпан, а затем переключаться на другой.

Или вы можете создать свою собственную структуру FILEPAIR (возвращаемую / заполненную join()), которая содержит ссылки на два FILE* s, и затем создавать специальные функции чтения, которые работают с этой структурой (например, fread2(void *ptr, size_t size, size_t nmemb, FILEPAIR *filePair)).

0 голосов
/ 25 октября 2018

Существует нет такой функции.Тебе нужно это написать самому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...