c++ использовать ifstream из памяти

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

теперь я хочу, не изменяя некоторый код, прочитать эти данные из памяти, на самом деле у меня есть char *, который содержит данные...

как я могу поставить мой char * данные ifstream без эффективного чтения файла?

5 ответов


если код, который использует ifstream& можно немного изменить, чтобы использовать istream& тогда вы можете легко переключаться между ifstream и istringstream (для чтения данных из памяти):

void read_data(std::istream& in)
{
}

звонящий:

std::istringstream in_stream(std::string("hello"));
read_data(in_stream);

std::ifstream in_file("file.txt");
read_data(in_file);

стандартная библиотека предлагает in-memory istream это тоже записи: std::stringstream.

вам нужно правильно абстрагировать свой код, чтобы он принимал общий istream вместо ifstream создать stringstream, заполните его своими данными и передайте это функции.

например:

const char* data = "Hello world";
std::stringstream str((std::string(data))); // all the parens are needed,
                                            // google "most vexing parse"

do_something_with_istream(str); // pass stream to your code

хотя использование std::istringstream (иногда ошибочно упоминается с ведущим i; такой класс тоже существует, но дороже строить, поскольку он также устанавливает выходной поток) очень популярен, я думаю, стоит отметить, что это делает, по крайней мере, одну копию фактической строки (Я подозреваю, что большинство реализаций создают две копии). Создание любой копии можно избежать с помощью тривиального буфера потока:

struct membuf: std::streambuf {
    membuf(char* base, std::ptrdiff_t n) {
        this->setg(base, base, base + n);
    }
};
membuf sbuf(base, n);
std::istream in(&sbuf);

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


возможно, вы ищете stringstream. http://www.cplusplus.com/reference/sstream/stringstream/. Я использовал это только один раз, и это было давно, но в основном вы можете передавать из места в памяти.


в моем проекте я использую методы write() и read () iostream, так как я пишу двоичные данные в stringstream. Извините, следующий код не тестируется и, вероятно, имеет синтаксические ошибки (ввод из office... ;- ), но что-то вроде этого позволяет записывать в память, файлы и в другое место (e. г. сетевые сокеты):

void foo(std::iostream *mystream)
{
    mystream.write("Hello", 5);
    uint32_t i=5302523;
    mystream.write((char*) &i, sizeof i);
}

int main()
{
    // Write to memory. stringstream's write() and read() work binary
    std::stringstream memstream;
    foo(&memstream);

    // Write to file
    std::fstream f;
    try
    {
        f.open("file.dat");
        foo(&f);
    }
    catch (...)
    {
        // ...
    }

    if (f.is_open())
        f.close();

    return EXIT_SUCCESS;
}