C++写入文件开头

12

我需要以ofstream的形式打开一个文件,并在文件前面写入内容,同时保留文件中剩余的内容,其余的内容将被“移动”。类似于“prepend”文件。

是否可以使用STL或boost实现这个功能?

3个回答

16

不行--在这里语言(或库)并不重要。大多数文件系统根本不允许这样做。

通常的方法是将新数据写入一个新文件,然后将旧文件中的数据复制到新文件中,在你写入的数据之后。


你怎么能说这是不可能的,然后又描述如何做到呢?Boost提供了一个可移植的文件系统库http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/index.htm,其中包括`boost::remove`函数,如果你想要unlink旧文件并创建新文件,它确实会有所作为——虽然这并非必要,甚至不是一种好的实现方式。OP没有要求一行代码解决问题,他需要的是帮助。 - Potatoswatter
7
他没有说明如何操作,而是描述了这个问题的标准解决方法。 - Nate
嗯,作为一种解决方法,这意味着完成任务。更重要的是,我们使用C++是因为它是可移植的,并且语言和库确实有所不同,因为非常特定的功能被用来解决问题。请参见我的答案。 - Potatoswatter
2
这里有一个明显但微妙的区别。Jerry并没有描述如何在文件前添加内容,而是创建了一个新文件,然后再追加旧文件。虽然这样也可以达到相同的结果,但对于操作系统来说肯定需要更多的工作量。(假设要添加的数据很小,而文件相对较大) - dominic

5

不,这样做是不行的。而且在这里已经有很多次问过了。如果您想要这样做,您需要创建一个新文件,将“prepend”数据写入其中,然后打开现有文件,将其内容复制到新文件中。


1
一个新的类可以包装这个功能。这假设您的前置数据不太大,可以轻松地适应内存。像常规的一样使用它。
#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中,不幸的是它不是虚拟的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接