【问题标题】:How to resume appending data to a file at a specific position? (std::ostream, streampos, tellp/seekp)如何恢复将数据附加到特定位置的文件? (std::ostream、streampos、tellp/seekp)
【发布时间】:2010-07-21 09:24:19
【问题描述】:

我正在尝试将一些数据附加到文件中,但在某些情况下,我想从末尾往回跳一点以覆盖文件的尾部。但是,seekp( pos )seekp( offset, relative ) 对我都没有任何影响(除了在使用负偏移量时抱怨)。是我用错了还是坏了?

下面是一个小例子。编译器:gcc 4.4.4版(Debian 4.4.4-6)

    #include <fstream>
    #include <sstream>
    #include <boost/date_time/posix_time/posix_time.hpp>
    using namespace std;
    using namespace boost::posix_time;

    int main(int nargs, char** pargs){
    if( nargs < 2 || nargs > 3 ){
     cerr<<"Usage: "<<pargs[0]<<" file [pos]"<<endl;
     return 1;
 }

 const char* fname = pargs[1];
 ofstream f( fname, ios::binary|ios::out|ios::ate );
 if( !f.good() ){
     cerr<<"Unable to open file!"<<endl;
     return 1;
 }

 if( nargs == 3 ){
     istringstream offss(pargs[2]);
     streamoff off;
     offss >> off;
     cout <<"Seeking to: "<<off<<endl;
     f.seekp( off, ios_base::end ); // using beg or cur instead doesn't help, nor does: seekp( off )
     if( f.fail() ){
  cerr<<"Unable to seek!"<<endl;
  f.clear(); // clear error flags
     }
 }

 f<<"[appending some data at "<<second_clock::local_time()<<"]\n";

 return 0;
    }

现在,如果我使用 0 偏移量查找,它应该将输出位置放在文件末尾并且写入应该追加,对吗?好吧,它对我没有任何影响(osf 以前不是空的):

> ./ostream_app_pos osf 0
Seeking to: 0
> cat osf
[appending some data at 2010-Jul-21 11:16:16]

通常的追加方式是使用ios::app。在这种情况下,追加有效,但尝试使用 neg/pos 偏移量没有效果,因为(来自 gcc doc):

ios::app 在每次写入之前寻找文件末尾。

我也尝试过既不使用ios::ate 也不使用ios::app(可能是截断模式),效果与ios::ate 相同。

对不起,如果这读起来更像是一个错误报告,但我想检查一下我在使用 seekp 时是否有什么错误,并了解它是否是特定于编译器的。

【问题讨论】:

  • 我不是这方面的专家,但请尝试使用 std::fstream 而不是 ofstream 并在打开文件时使用 std::ios::in ;我知道一点文件流的内部结构,我认为这可能会有所帮助
  • 布里尔,谢谢!知道这是仅 gcc 还是常见的事情?我会尽快测试至少 MSVC,但这里没有安装它...

标签: c++ ofstream seek


【解决方案1】:

您需要打开具有输入和输出属性的文件。
以下代码没有通常的错误处理,只是为了说明一种技术。

#include <iostream>
#include <fstream>

int main()
{
    const char *szFname = "c:\\tmp\\tmp.txt";
    std::fstream fs(szFname, 
                    std::fstream::binary | 
                    std::fstream::in     | 
                    std::fstream::out);
    fs.seekp(13, std::fstream::beg);
    fs << "123456789";

    return 0;
}

================================================= =

C:\Dvl\Tmp>type c:\tmp\tmp.txt
abdcefghijklmnopqrstuvwxyz
C:\Dvl\Tmp>Test.exe
C:\Dvl\Tmp>type c:\tmp\tmp.txt
abdcefghijklm123456789wxyz
C:\Dvl\Tmp>

【讨论】:

  • 谢谢。这实际上与 Tomaka17 已经给出的答案相同!
猜你喜欢
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
  • 2011-08-24
  • 2022-11-15
相关资源
最近更新 更多