C - создать файл в памяти

Я пишу небольшую программу на простом C здесь. Мне нужно создать файл непосредственно внутри памяти (не записанный на жесткий диск) В настоящее время я могу использовать fopen("filename.txt,"wb") для записи в файл.

Я знаю, что в linux вы можете использовать fmemopen(). Есть ли аналогичное решение для win32?

Ответ 1

fdopen находится в POSIX.1-1990, и Windows поддерживает его в форме _fdopen. Используя его вместе с _get_osfhandle и _open_osfhandle, он позволяет создать надлежащий FILE * из файла Windows HANDLE который работает с остальной частью стандартной библиотеки C. См. Также вопрос. Существует ли Windows, аналогичная fdopen для HANDLE? для получения дополнительной информации об этом.

Теперь остальной частью проблемы является создание файла Windows с резервной копией памяти. Оказывается, есть разные подходы к этому, которые приближают это под NT. Наиболее распространенным является:

  1. Создание временного файла; то есть непостоянный. Другими словами, используйте CreateFile с путем, созданным из GetTempPath и, возможно, GetTempFileName.

  2. ... с установленным FILE_ATTRIBUTE_TEMPORARY файла FILE_ATTRIBUTE_TEMPORARY [1]; то есть, насколько это возможно, поддерживается памятью.

  3. ... и с установленным FILE_FLAG_DELETE_ON_CLOSE [2]; то есть намек на то, что его никогда не нужно будет писать, если он не умещается в памяти.

До тех пор, пока памяти достаточно для хранения файла (т.е. достаточно низкого давления памяти), диск не будет использоваться. Посмотрите этот пост MSDN от Ларри Остермана, который описывает этот подход. Забавно, он называет такие файлы "временными" временными файлами.

Обратите внимание, что это не совсем эквивалентно fmemopen, который завершится неудачей, если файл не помещается в предопределенную область памяти [3] (т. fmemopen устанавливает fmemopen с чистой памятью). Однако для многих целей это достаточно близко (и иногда может потребоваться потенциальная поддержка на диске).

Кроме того, см. Как предотвратить сброс на диск карты памяти, открытой во временном файле удаления-при-закрытии Windows, обсуждается некоторое обсуждение этих атрибутов файла и других возможных подходов.

Наконец, для полного примера, который объединяет обе части (т.е. создает файл с поддержкой памяти и затем оборачивает его в дескриптор FILE *), взглянем на реализации из библиотеки fmem (которая была написана для обеспечения кроссплатформенности). решение этой проблемы) или по одному из библиотеки libconfuse.


[1]

Указание атрибута FILE_ATTRIBUTE_TEMPORARY заставляет файловые системы избегать записи данных обратно в FILE_ATTRIBUTE_TEMPORARY хранилище, если доступно достаточное количество кэш-памяти, поскольку приложение удаляет временный файл после закрытия дескриптора. В этом случае система может полностью избежать записи данных. Хотя он напрямую не управляет кэшированием данных так же, как ранее упомянутые флаги, атрибут FILE_ATTRIBUTE_TEMPORARY сообщает системе как можно больше хранить в системном кэше без записи и, следовательно, может представлять интерес для определенных приложений.

[2]

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

[3]

Попытки записать в буфер больше байтов размера приводят к ошибке.

Ответ 2

Такая функциональность не поддерживается внутри Windows. Однако вы можете переписать высокоуровневые функции stdio для доступа к буферу памяти, а не к файлу, или просто реализовать stdio-подобные функции. Или вы можете реализовать RAM-диск, однако установка самого драйвера RAM-диска может не соответствовать вашему правилу "не записывать на диск".

Ответ 3

Я бы не использовал fopen, так как это создает файл.

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

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

Ответ 4

Вы можете достичь чего-то близкого с MapViewOfFile. Win32 API, который вы должны использовать для этого:

CreateFile (...)

CreateFileMapping (...)

MapViewOfFile (...)

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