C ++ запись в начало файла - PullRequest
11 голосов
/ 02 апреля 2010

Мне нужно открыть файл как ofstream и записать в начало файла, сохранив при этом оставшееся содержимое файла, которое будет «перемещено». Похож на "готовый" файл.

Возможно ли это с помощью STL или boost?

Ответы [ 3 ]

16 голосов
/ 02 апреля 2010

Нет - язык (или библиотека) здесь не имеет большого значения. Большинство файловых систем просто не позволяют этого, полная остановка.

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

5 голосов
/ 02 апреля 2010

Нет, это не так. И об этом здесь уже много раз спрашивали. Если вы хотите сделать это, вам нужно создать новый файл, записать в него данные «prepend», затем открыть существующий файл и скопировать его содержимое в новый файл.

1 голос
/ 02 апреля 2010

Новый класс iostream может обернуть эту функциональность. Это предполагает, что ваши данные prepend не слишком велики, чтобы удобно помещаться в памяти. Используйте это как обычный ofstream.

#include <fstream>
#include <sstream>
#include <vector>

class prepend_ofstream
    : public std::ostringstream {
    std::filebuf file;
public:
    prepend_ofstream() {}
    prepend_ofstream( char const *name, openmode mode = out ) {
        open( name, mode );
    }
    ~prepend_ofstream() {
        if ( is_open() ) close();
    }
    void open( char const *name, openmode mode ) {
        if ( ! file.open( name, mode & binary | in | out ) ) {
            setstate( failbit );
        }
    }
    bool is_open() { return file.is_open(); }
    void close() {
        if ( ! is_open() ) {
            setstate( failbit );
            return;
        }
        char *strbuf = &str()[0];
        std::vector<char> buf( str().size() );
        int rdsz;
        do {
            rdsz = file.sgetn( &buf[0], buf.size() );
            file.pubseekoff( -rdsz, cur );
            file.sputn( strbuf, buf.size() );
            file.pubseekoff( 0, cur ); // "update the output sequence"
            std::copy( &buf[0], &buf[0]+rdsz, strbuf );
        } while ( rdsz == buf.size() );
        file.sputn( &buf[0], rdsz );
        if ( ! file.close() ) {
            setstate( failbit );
        }
    }
};

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

...