2011-09-10 14 views
27

यूनिक्स में, यदि आपके पास फ़ाइल डिस्क्रिप्टर है (उदा। सॉकेट, पाइप, या आपकी मूल प्रक्रिया से विरासत में), तो आप fdopen(3) पर एक buffered I/O FILE* स्ट्रीम खोल सकते हैं।क्या विंडोज़ हैंडल के लिए fdopen के बराबर है?

क्या HANDLE एस के लिए विंडोज़ के बराबर है? यदि आपके पास HANDLE है जो आपकी मूल प्रक्रिया (stdin, stdout, या stderr से अलग) या CreatePipe से पाइप से विरासत में मिला है, तो क्या इससे FILE* स्ट्रीम को बफर किया जा सकता है? एमएसडीएन दस्तावेज _fdopen करता है, लेकिन यह _open द्वारा वापस पूर्णांक फ़ाइल डिस्क्रिप्टर के साथ काम करता है, जेनेरिक HANDLE एस नहीं।

उत्तर

31

दुर्भाग्यवश, HANDLE एस FILE* एस और फाइल डिस्क्रिप्टर से पूरी तरह से अलग जानवर हैं। सीआरटी आखिरकार HANDLE एस के संदर्भ में फ़ाइलों को संभालता है और उन HANDLE एस को फाइल डिस्क्रिप्टर से जोड़ता है। उन फाइल डिस्क्रिप्टर बदले में संरचना सूचक को FILE* से पीछे रखता है।

:

सौभाग्य से, this MSDN page पर एक अनुभाग है कि कार्यों का वर्णन करता है "एक फ़ाइल संरचना, एक फ़ाइल वर्णनकर्ता के बीच फ़ाइल प्रदर्शन बदलने के लिए एक तरीका प्रदान करते हैं, और एक Win32 फ़ाइल हैंडल" है

  • _fdopen, _wfdopen: कि था पहले से निम्न स्तर के आई/ओ के लिए खोल दिया और खुले धारा के लिए सूचक रिटर्न एक फ़ाइल के साथ एक धारा एकत्रित करती है।
  • _fileno: स्ट्रीम से जुड़े फाइल डिस्क्रिप्टर को प्राप्त करता है।
  • _get_osfhandle: वापसी ऑपरेटिंग सिस्टम फ़ाइल संभाल मौजूदा सी चलाने के समय फ़ाइल वर्णनकर्ता
  • _open_osfhandle साथ जुड़े: एसोसिएट्स सी एक मौजूदा ऑपरेटिंग सिस्टम फ़ाइल हैंडल रन-टाइम फ़ाइल वर्णनकर्ता।

आपको क्या चाहिए _open_osfhandle_fdopen द्वारा पीछा किया जाता एक HANDLE से एक FILE* प्राप्त करने के लिए की तरह लग रहा।

यहां एक उदाहरण है जिसमें CreateFile() से प्राप्त किया गया है। जब मैंने इसे परीक्षण किया है, यह फ़ाइल "test.txt" के पहले 255 वर्णों से पता चलता है और संलग्न कर देता है फ़ाइल के अंत में "--- नमस्ते विश्व ---!":

#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); 
     } 
    } 
} 

इस के लिए काम करना चाहिए पाइप भी।

संबंधित मुद्दे