2011-09-10 18 views
27

Unixでは、ソケット、パイプ、または親プロセスから継承したファイル記述子がある場合は、fdopen(3)でバッファされたI/O FILE*ストリームを開くことができます。ハンドル用のfdopenに相当するWindowsはありますか?

WindowsにHANDLEの同等の機能はありますか?親プロセス(stdin、stdout、stderrと異なる)またはパイプCreatePipeから継承されたHANDLEがある場合は、バッファされたFILE*ストリームを取得できますか? MSDNは_fdopenというドキュメントを持っていますが、これは_openによって返された整数ファイル記述子で動作します。一般的なHANDLEではありません。

答えて

31

残念ながら、HANDLEは、FILE*とファイル記述子とは全く異なる獣です。 CRTは最終的にファイルをHANDLEで処理し、それらのファイルをファイル記述子に関連付けます。それらのファイルディスクリプタは、構造ポインタをFILE*で返します。

幸い、という機能について説明しthis MSDN pageの「FILE構造、ファイル記述子の間でファイルの表現を変更する方法を提供し、そしてWin32のファイルハンドル」があります

  • _fdopen_wfdopenは: 以前に低レベルI/Oのために開かれ、開放 ストリームへのポインタを返したファイルとストリームを関連付け。
  • _fileno:ストリームに関連付けられたファイル記述子を取得します。
  • _get_osfhandle
  • _open_osfhandle既存のCランタイムファイルディスクリプタに に関連戻るオペレーティング・システムのファイルハンドル:アソシエイツは、実行時間C 既存のオペレーティング・システムのファイルハンドルとファイルディスクリプタを。

あなたはHANDLEからFILE*を得ることが_fdopen続い_open_osfhandleで必要なもののように見えます。

CreateFile()から得られたHANDLEの例です。私はそれをテストしたとき、それはファイル「test.txtという」の最初の255個の文字を表示し、追加したファイルの末尾に「---のHello Worldを---!」:

#include <windows.h> 
#include <io.h> 
#include <fcntl.h> 
#include <cstdio> 

int main() 
{ 
    HANDLE h = CreateFile("test.txt", GENERIC_READ | GENERIC_WRITE, 0, 0, 
     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 
    if(h != INVALID_HANDLE_VALUE) 
    { 
     int fd = _open_osfhandle((intptr_t)h, _O_APPEND | _O_RDONLY); 
     if(fd != -1) 
     { 
      FILE* f = _fdopen(fd, "a+"); 
      if(f != 0) 
      { 
       char rbuffer[256]; 
       memset(rbuffer, 0, 256); 
       fread(rbuffer, 1, 255, f); 
       printf("read: %s\n", rbuffer); 
       fseek(f, 0, SEEK_CUR); // Switch from read to write 
       const char* wbuffer = " --- Hello World! --- \n"; 
       fwrite(wbuffer, 1, strlen(wbuffer), f); 
       fclose(f); // Also calls _close() 
      } 
      else 
      { 
       _close(fd); // Also calls CloseHandle() 
      } 
     } 
     else 
     { 
      CloseHandle(h); 
     } 
    } 
} 

これがために働く必要がありますパイプも同様です。