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

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

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

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


person ghiboz    schedule 27.11.2012    source источник
comment
Возможный дубликат Установка внутреннего буфера, используемого стандартным потоком (pubsetbuf)   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 31.03.2017


Ответы (5)


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

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);
person hmjd    schedule 27.11.2012

Хотя использование 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);

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

person Dietmar Kühl    schedule 27.11.2012

Стандартная библиотека предлагает 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
person Jon    schedule 27.11.2012

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

person Matthew    schedule 27.11.2012

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

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;
}
person wizard    schedule 03.06.2016