Можно ли адаптировать функцию записи на диск для записи в память? - PullRequest
0 голосов
/ 23 мая 2018

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

int manipulateAndWrite(const char *filename,
                       const FOO_DATA *data);

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

Чтобы получить результаты, мне в настоящее время необходимо прочитать их из файла.Я предпочел бы избежать записи в файл и чтения из файла и вместо этого получить результаты в буфер памяти.

Могу ли я передать путь к файлу, который указывает запись в память вместо файловой системы

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Да, у вас есть несколько вариантов, хотя POSIX поддерживает только первое приведенное ниже предложение.Остальные зависят от ОС и могут не переноситься во все системы POSIX, хотя я верю, что они работают во всех системах POSIXy.

  • Вы можете использовать именованныйpipe (FIFO) и иметь вспомогательный поток, считываемый из него одновременно с функцией записи.

    Поскольку самого файла нет, служебные данные - это просто системные вызовы (запись и чтение);в основном просто накладные расходы на межпроцессное взаимодействие, не о чем беспокоиться.Чтобы сэкономить ресурсы, создайте вспомогательный поток с небольшим стеком (используя pthread_attr_ и т. Д.), Так как размер стека по умолчанию имеет тенденцию быть огромным (порядка нескольких мегабайт; 2*PTHREAD_STACK_SIZE должно быть достаточно для вспомогательных потоков.)

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

  • Во многих системах POSIXy,Вы можете создать трубу или пару сокетов и получить к ней доступ через /dev/fd/N, где N - номер дескриптора в десятичном виде.(В Linux /proc/self/fd/N также работает.) Это не обязательно для POSIX, поэтому может быть доступно не во всех системах, но большинство его поддерживают.

    Таким образом, фактического файла как такового не существует,и функция пишет в канал или сокет.Если данные, записанные функцией, не превышают PIPE_BUF байтов, вы можете просто прочитать данные из канала впоследствии;в противном случае вам необходимо создать вспомогательный поток для чтения из канала или сокета одновременно с функцией, иначе запись будет блокирована.

    В этом случае также минимальные накладные расходы.

  • В системах POSIXy на основе ELF (в основном, во всех) вы можете вставлять системные вызовы open(), write() и close() или функции библиотеки C.

    (В Linux есть два основных подхода, один с использованием компоновщика --wrap, а другой с dlsym(). Оба прекрасно работают в этом конкретном случае. Эта способность вставлять функции основана на том, как исполняются двоичные файлы ELF.связывается во время выполнения и не имеет прямого отношения к POSIX.)

    Сначала вы настраиваете вставляющие функции, так что open() определяет, соответствует ли имя файла вашему специальному файлу "в памяти", и возвращаетвыделенный номер дескриптора для него.(Вам также может понадобиться вставить другие функции, такие как ftruncate() или lseek(), в зависимости от того, что функция на самом деле делает; в Linux вы можете запустить двоичный файл под ptrace, чтобы проверить, какие системные вызовы он фактически использует.)

    Когда write() вызывается с выделенным номером дескриптора, вы просто memcpy() записываете его в буфер памяти.Вам потребуется использовать глобальные переменные для описания выделенного размера, используемого размера и указателя на буфер памяти, и, возможно, быть готовым изменить размер / увеличить буфер при необходимости.

    Когда вызывается close()с выделенным номером дескриптора вы знаете, что буфер памяти заполнен, а содержимое готово к обработке.

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

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

    Приложению не нужно пытаться искать файловую систему на основе ОЗУ: выбор такой:и должно быть, до пользователя.Приложение не должно заботиться даже о том, какая файловая система используется, и должно просто использовать указанный каталог.

0 голосов
/ 23 мая 2018

Вы не можете использовать эту библиотечную функцию.Посмотрите на это, как записывать в файлы в памяти: Возможно ли создать объект C FILE для чтения / записи в память

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