如何在文件的特定位置恢复追加数据? (std::ostream、streampos、tellp/seekp)

发布于 2024-09-11 02:45:19 字数 1736 浏览 3 评论 0原文

我正在尝试将一些数据附加到文件中,但在某些情况下希望从末尾跳回一点以覆盖文件的尾部。但是, 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 文档):

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

我还尝试既不使用 ios::ate 也不使用 ios::app(大概是截断模式),其效果与 ios::ate 相同。

抱歉,如果这读起来很像错误报告,但我想检查一下在使用 seekp 时是否出了问题,并了解它是否是特定于编译器的。

I'm trying to append some data to a file, but in some cases want to skip back a bit from the end to overwrite the tail end of the file. However, neither seekp( pos ) nor seekp( offset, relative ) is having any effect for me (except complaining when using a negative offset). Am I using them incorrectly or are they broken?

A little example follows. Compiler: gcc version 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;
    }

Now, if I seek using a 0 offset, it should place the output-position at the end of the file and writes should append, right? Well, it's having no effect for me (osf was not previously empty):

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

The usual way of appending is to use ios::app. In this case, appending works, but trying to seek with a neg/pos offset has no effect, since (from gcc doc):

ios::app Seek to end of file before each write.

I also tried using neither ios::ate nor ios::app (presumably truncate mode), to the same effect as ios::ate.

Sorry if this reads rather like a bug report, but I wanted to check whether there's something I've got wrong here in the usage of seekp and get an idea of whether it's compiler-specific.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奈何桥上唱咆哮 2024-09-18 02:45:19

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

#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>

You need to open the file with both input and output attributes.
The following code doesn't have the usual error handling, it is just to illustrate a technique.

#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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文