Я хочу записать в начало большого файла, используя C ++, используя fstream.
Метод, который я придумал, состоит в том, чтобы записать все данные во временный файл, затем записать в исходный файл и затем скопировать данные из файла tmp в исходный файл.

Я хочу создать буфер, который будет переносить данные из исходного файла в файл tmp и наоборот.
Процесс работает для всех: string, ostringstream и stringstream. Я хочу, чтобы копирование данных происходило быстро и с минимальным потреблением памяти.

ПРИМЕР с string:

void write(std::string& data)
{
    std::ifstream fileIN("smth.txt");
    std::ofstream fileTMP("smth.txt.tmp");
    std::string line = "";

    while(getline(fileIN, line))
        fileTMP << line << std::endl;

    fileIN.close();
    fileTMP.close();

    std::ifstream file_t_in("smth.txt.tmp"); // file tmp in
    std::ofstream fileOUT("smth.txt");
    fileOUT << data;

    while(getline(file_t_in, line)
        fileOUT << line << std::endl;

    fileOUT.close();
    file_t_in.close();

    std::filesystem::remove("smth.txt.tmp");
}

Что мне следует использовать для этого: string или ostringstream или stringstream?

В чем преимущество использования одного перед другим?

0
Someone 9 Окт 2021 в 16:24

2 ответа

Лучший ответ

Предполагая, что есть хотя бы какая-то операция и вы не копируете дважды одни и те же данные, чтобы закончить неизменным файлом, возможные улучшения (ИМХО):

  • не используйте std::endl внутри цикла, а только '\n' или "\n". std::endl записывает конец строки, но также вызывает сброс базового потока, что бесполезно и дорого внутри цикла.
  • код копирует данные дважды. Гораздо эффективнее, если возможно, создать временный файл путем копирования (как это делает ваш код в настоящее время), а затем удалить старый файл и переименовать временный файл с исходным именем. Таким образом, вы копируете данные только один раз, потому что переименование файла - дешевая операция.
2
Serge Ballesta 9 Окт 2021 в 13:32

Копировать вручную не нужно, есть std::filesystem::copy .

Если вы действительно хотите копировать с использованием файловых потоков, вы можете использовать однострочник: output_stream << input_stream.rdbuf();.

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

2
HolyBlackCat 9 Окт 2021 в 13:30