2012-03-07 17 views
2

バイナリファイル内のランダムな場所に書き込むためにwin32 WriteFile()を使用するレガシーコードを作成しています。書き込みのオフセットはファイルの最後を過ぎてもかまいません。この場合、WriteFile()は自動的にファイルサイズをオフセットに拡張し、データをファイルに書き込むようです。読み込み/書き込みfstreamの場所をシーク/ライトするときにファイルサイズを自動的に拡張

私は同じことを行うためにstd::fstreamを使用するようにしたいのですが、私は適切な場所にseekp()しようとすると、ファイルの末尾を越えて、seekp()は失敗し、その後のwrite()が同様に失敗しました。

私は、現在のEOFと書きたい場所の間のスペースを '手動で'入力する必要があると思います。

コードは次のようになります。

void Save(size_t offset, const Element& element) 
{ 
    m_File.seekp(offset, std::ios_base::beg); 
    m_File.write(reinterpret_cast<const char*>(&element), sizeof(Element)); 
    if (m_File.fail()) { 
     // ... error handling 
    } 
} 

だから、「手動」に私の唯一のオプションはoffsetに、現在のEOFのアップから0 Sを書くのですか?ここで

答えて

1

は私がMSDNからそのまま拾った例です。

// basic_ostream_seekp.cpp 
// compile with: /EHsc 
#include <fstream> 
#include <iostream> 

int main() 
{ 
    using namespace std; 
    ofstream x("basic_ostream_seekp.txt"); 
    streamoff i = x.tellp(); 
    cout << i << endl; 
    x << "testing"; 
    i = x.tellp(); 
    cout << i << endl; 
    x.seekp(2); // Put char in third char position in file 
    x << " "; 

    x.seekp(2, ios::end); // Put char two after end of file 
    x << "z"; 
} 

ファイル「basic_ostream_seekp.txt」はプログラムの最後にte ting\0\0z、すなわちを持っている、あなたはの終わりを過ぎて求めることを許可されていますファイル。

いずれにしても、書き込みが失敗した場合は、seekpもチェックすることができます。そうであれば、以前に障害を検出できます。

+0

申し訳ありませんが、私はstd :: fstreamベースのコードを削除してしまいました。なぜなら、CRTは最大2k個のファイルハンドルしか割り当てることができず、それだけでは十分ではありませんでした。あなたの答えは - ios :: endからの検索は実際に動作するようです。不思議なことに、ios :: seeを探すことは失敗します。 – liwp

+0

私はファイルの終わりを過ぎて探していました。私はWindows上のVS 2010とLinux上のかなり新しいバージョンのGCC(現在の2つのプラットフォーム)をテストし、 'ios :: beg'は' ios :: end'と同様に動作しました。[編集:私は明示的に 'ios :: beg'を指定するのではなく、' seekp'の1つの引数形式を使用したと思います。たぶん 'ios :: beg'は何か他の理由でliwpに失敗したでしょうか?私の場合、ファイルは 'ios :: in |イオス::アウト| ios :: binary';それが違いを生むかどうかはわかりません。私は、「ファイルの過去の終わり」のケースについて、実際にはほとんど書かれていないことが分かりました。 – entheh

関連する問題