2011-02-04 20 views
3

std :: ofstream(Visual C++ 2005)から基本ファイルハンドルを取得できますか?std :: ofstreamからハンドルを取得する

これは、この質問の反対です:

Can I use CreateFile, but force the handle into a std::ofstream?

私は、これはのCreateFileでファイルを開くことなく、ファイル(例えば、作成時間)の属性を変更することにしたい理由。

+0

標準ライブラリは標準的なものなので、オペレーティングシステムによってはそれに応じて機能を提供することができません。それはどこでも働かなければならない。したがって、C++では答えはノーですが、非標準のC++では可能です。後者がオプションであるかどうかはわかりませんが、あなたはちょうど「長い」道を歩かなければならないかもしれませんが、それがはっきりしていることを確認したいと思いました。 – GManNickG

+0

私はVisual C++ – mpipe3

答えて

4

C++標準では、ofstreamの生ファイル記述子を指定または取得する手段が提供されていないため、これは可能ではありません。 ですが、HANDLEとの間でストリームバッファリングを実装するカスタムstreambufクラスを構築し、そのバッファを使用するカスタムostream型を定義することが可能です。私はそれが本当にあなたが探しているものかどうかは分かりませんが、実行可能な選択肢です。

+0

+1で働いていたソリューションを使用して満足しました。そして最もクリーンなオプションです。 –

+0

Downvoter-この回答が間違っていることを説明できますか? – templatetypedef

1

いいえの中にFILE*(または内部で知られているように_Filet*)にアクセスすることはできません。

0

VisualC++ 2010ライブラリでは、次のように動作するはずです。私はそれがVisualC++ 2005と同じだと仮定していますが、あなたは確認する必要があります:

FILE* fh = fopen(...); 

HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fh)); 
// do something on hFile 

// create iostream from FILE 
std::ifstream ifs(fh); 

// use it... 

// close FILE 
_close(fh); 
+1

'std :: ifstream'にそのようなコンストラクタがありません。これは拡張か野生の推測ですか? – GManNickG

+1

これはVC10の(文書化されていない!)拡張です - 私はVC2005についてはわかりませんが、私はそれもそこにあると仮定します。 OPに将来の解決策が必要な場合は、@templatetypedefのようにカスタムのstreambufも実装します。 –

+0

これは、あなたの答えの延長としてVC10でしか動作しないことに言及する必要があります。 – GManNickG

1

これは標準C++では不可能です。しかし、Boost.IOStreamsライブラリではそれほど難しくありません。 Deviceを作成し、boost::iostreams::stream_buffer<>にラップし、boost::iostreams::stream<>を使用して適切なストリームを追加します。

3

私の答えは「私はUnixの開発者であり、Windowsの開発者ではありません」と書かれています。しかし私はあなたと同じ問題を抱えていました。これが私がそれに対処する方法です。私はより良い答えをしたいです。下の私の答えは、あなたの肌をクロールさせるが、それは働いた。

まず、fdbufの_Filet *が必要です。これはプライベートメンバーなので、新しいクラスを作成するだけでは表示できません。だから、fstreamのヘッダーを修正して、filebufに新しいfriend関数を追加して、その特定の関数が私たちに不正行為をさせ、そのメンバへのアクセスを許可するようにします(定義 "_Filet * _Myfile;"のすぐ下に追加しました):

friend HANDLE __HACK_getFilebufHANDLE(filebuf*); 

ここでプライベートメンバーにアクセスするための公開機能があります。ステップ2は、関数を記述することです。そのRDBUFが間違った型(IOBUFではなくたfilebuf)を返す以外

namespace std { 
    HANDLE __HACK_getFilebufHANDLE(filebuf*in) { 
     return (HANDLE) _get_osfhandle(_fileno(in->_Myfile)); 
    } 
}; 

最後に、あなただけの、それを呼び出す必要があります。 誰もがスキンクロールを行うことがあります(実際には、派生型へのキャストを検証するためにここでタイプチェックを行います):

__HACK_getFilebufHANDLE((filebuf*)fopoutstrm.rdbuf()) 

申し訳ありませんが私はよりクリーンな答えを持っていません。

関連する問題