C++ C++;写入文件的前面

C++ C++;写入文件的前面,c++,file,io,C++,File,Io,我需要以流的形式打开一个文件并写入文件的前面,同时保留 文件的剩余内容,将被“移动”。类似于“prepend” 档案 使用STL或boost是否可以实现这一点?不可以。这在这里已经被问过很多次了。如果要执行此操作,您必须创建新文件,将“prepend”数据写入其中,然后打开现有文件并将其内容复制到新文件中。否--语言(或库)在这里没有多大区别。大多数文件系统都不允许这样做,到此为止 获得相同效果的通常方法是将新数据写入新文件,然后在写入数据之后将旧文件中的数据复制到新文件。新的iostream类

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


使用STL或boost是否可以实现这一点?

不可以。这在这里已经被问过很多次了。如果要执行此操作,您必须创建新文件,将“prepend”数据写入其中,然后打开现有文件并将其内容复制到新文件中。

否--语言(或库)在这里没有多大区别。大多数文件系统都不允许这样做,到此为止


获得相同效果的通常方法是将新数据写入新文件,然后在写入数据之后将旧文件中的数据复制到新文件。

新的
iostream
类可以包装该功能。这假设您的前置数据不会太大而无法轻松放入内存。像流的常规
一样使用它

#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 );
        }
    }
};
#包括
#包括
#包括
流的预结束_类
:public std::ostringstream{
std::filebuf文件;
公众:
预结束流()的_{}
流的前置_(char const*name,openmode=out){
打开(名称、模式);
}
~prepend_of stream(){
如果(是开的())是关的();
}
无效打开(字符常量*名称,openmode模式){
如果(!file.open(名称、模式和二进制输入输出)){
设置状态(故障位);
}
}
bool is_open(){return file.is_open();}
无效关闭(){
如果(!is_open()){
设置状态(故障位);
返回;
}
char*strbuf=&str()[0];
std::vector buf(str().size());
int-rdsz;
做{
rdsz=file.sgetn(&buf[0],buf.size());
文件pubsekoff(-rdsz,cur);
file.sputn(strbuf,buf.size());
file.pubseekoff(0,cur);//“更新输出序列”
std::copy(&buf[0],&buf[0]+rdsz,strbuf);
}而(rdsz==buf.size());
sputn文件(&buf[0],rdsz);
如果(!file.close()){
设置状态(故障位);
}
}
};

通常,功能是通过新的流缓冲区类添加的,而不是实际的流,但在这种情况下,新功能位于
close
,不幸的是,它不是虚拟的。

您如何说这是不可能的,然后描述如何做到这一点?Boost提供了一个带有
Boost::remove
的可移植文件系统库,如果您想取消旧文件的链接并生成一个新文件,它实际上会有所不同——这不是必需的,甚至不是实现它的好方法。OP并没有要求一个班轮,他要求帮助。他并没有描述如何做到这一点;他描述了这个问题的标准解决方案。呃,作为一个解决方案意味着完成任务。更重要的是,我们使用C++,因为它是可移植的,语言和库确实有区别,因为非常具体的特征被用来解决这个问题。看我的答案。这里有一个明显但微妙的区别。jerry并没有描述如何在一个文件中添加前缀,他正在创建一个新文件,然后附加旧文件。这实现了相同的结果,但对于操作系统来说肯定要做更多的工作。(假设要预加的数据很小,而文件比较大)