ФАЙЛ C ++ без записи на диск - PullRequest
8 голосов
/ 02 мая 2011

Я использую библиотеку, которая имеет довольно много функций, которые записывают в FILE, но ни одна из которых, кажется, не может удобно выгружать те же данные в объект в памяти. Есть ли способ создать объект FILE (или переопределить его), который хранит данные в памяти вместо записи на диск - я хотел бы избежать снижения производительности открытия / записи / чтения из файлов снова и снова .

ОБНОВЛЕНИЕ: за предложение Роба, пробуя поток строк:

ss.put(c);

std::string myval = ss.str();

printf("Value: %s\n after writing: %i length %lu\n",myval.c_str(),c, myval.length());

Но теперь попытка получить данные (двоичные данные) из потока строк застряла - как мне получить двоичные данные, которые я добавляю?

Ответы [ 5 ]

10 голосов
/ 02 мая 2011

Помимо уже упомянутого GNU fmemopen(), который известен в POSIX как open_memstream , можно получить аналогичное решение, комбинируя mmap() (используя MAP_ANONYMOUS) или любую другую специфическую для ОС функцию, котораявозвращает дескриптор файла в блок памяти, и fdopen().

EDIT: это неправильно, mmap не создает дескриптор файла.

5 голосов
/ 02 мая 2011

В GNU libc есть, например, fmemopen, который даст вам FILE *, который записывает в память. Попробуйте man fmemopen в вашей системе Linux для деталей.

Я подозреваю (но не знаю наверняка), что fmemopen - это обертка, которая управляет подходом mmap / fdopen, упомянутым @ Cubbi.

2 голосов
/ 26 июня 2012

Если вы работаете в Mac OS X или iOS, у вас нет доступа к fmemopen. Я с открытым исходным кодом решение здесь:

http://jverkoey.github.com/fmemopen/

1 голос
/ 02 мая 2011

Если у вас есть возможность изменить вашу библиотеку, вы можете использовать потоки C ++ вместо потоков C FILE.

Если ваша старая библиотечная функция выглядела так:

void SomeFun(int this, int that, FILE* logger) {
  ... other code ...
  fprintf(logger, "%d, %d\n", this, that);
  fputs("Warning Message!", logger);
  char c = '\n';
  fputc(c, logger);
}

, вы можетезамените этот код на:

void SomeFun(int this, int that, std::ostream& logger) {
  ... other code ...
  logger << this << ", " << that << "\n";
  // or: logger << boost::format("%d %d\n") %this %that;
  logger << "Warning Message!";
  char c = '\n';
  logger.put(c);
  // or: logger << c;
}

Затем в своем небиблиотечном коде сделайте что-то вроде:

#include <sstream>    
std::stringstream logStream;
SomeFun(42, 56, logStream);
DisplayCStringOnGui(logStream.str().c_str());
0 голосов
/ 02 мая 2011

Рассмотрите возможность установки tmpfs и попросите приложение написать в него. Конечно, это только * nix.

...