Объединить два указателя на файл

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

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

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

Eugene Sh. 25.10.2018 16:16

Я хочу создавать не физический файл на диске, а виртуальный файл так же, как это делает popen.

BlackCap 25.10.2018 16:18

определите пожалуйста "виртуальный" файл?

Tom's 25.10.2018 16:19
popen создает трубка для созданного процесс.
Eugene Sh. 25.10.2018 16:19

@ Tom виртуальный в том смысле, что это не реальный файл, который где-то хранится, а процесс, который лениво производит вывод.

BlackCap 25.10.2018 16:23
stackoverflow.com/questions/35272652/…
Antti Haapala 25.10.2018 16:25

@BlackCap Используете указатель FILE для управления им? Что ж, я буду следить за вопросом, потому что мне кажется слишком сложным иметь указатель FILE.

Tom's 25.10.2018 16:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
183
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Есть такая функция нет. Вам нужно написать самому.

Я полный новичок в C. Не могли бы вы рассказать, как я могу создать join?

BlackCap 25.10.2018 16:23

@BlackCap попробуйте это. Это создаст третий файл. Возможно, вам это не нужно, тогда вы можете просто читать файлы в цикле, сначала файл a, затем файл b.

gsamaras 25.10.2018 16:23

Ссылка создает физический файл на диске, а это не то, что я ищу.

BlackCap 25.10.2018 16:25
Ответ принят как подходящий

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

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

Это похоже на то, что я ищу

BlackCap 25.10.2018 16:30

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

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

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

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

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

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!

Другие вопросы по теме