2011-09-10 39 views
27

Trong Unix, nếu bạn có bộ mô tả tệp (ví dụ: từ ổ cắm, đường ống hoặc được kế thừa từ quy trình gốc), bạn có thể mở luồng I/O FILE* được đệm trên đó với fdopen(3).Có tương đương Windows với fdopen cho HANDLE không?

Có tương đương trên Windows cho HANDLE s không? Nếu bạn có số HANDLE được thừa hưởng từ quy trình gốc của bạn (khác với stdin, stdout hoặc stderr) hoặc đường ống từ CreatePipe, bạn có thể nhận luồng được lưu vào bộ đệm là FILE* không? MSDN có tài liệu _fdopen, nhưng hoạt động với các bộ mô tả tệp số nguyên được trả về bởi _open, không phải là chung chung HANDLE s.

Trả lời

31

Thật không may, HANDLE s là những con thú hoàn toàn khác nhau từ FILE* và mô tả tệp. CRT cuối cùng xử lý các tệp theo điều khoản của HANDLE s và liên kết các tệp HANDLE đó với một bộ mô tả tệp. Những người mô tả tập tin này lần lượt quay trở lại con trỏ cấu trúc bằng cách FILE*.

May mắn thay, có một phần trên this MSDN page mô tả chức năng mà "cung cấp một cách để thay đổi các đại diện của các tập tin giữa một FILE cấu trúc, một bộ mô tả tập tin, và một tập tin Win32 xử lý":

  • _fdopen, _wfdopen: Liên kết luồng với tệp được mở trước đó cho I/O cấp thấp và trả về con trỏ tới luồng mở .
  • _fileno: Nhận bộ mô tả tệp được liên kết với luồng.
  • _get_osfhandle: Return hệ điều hành xử lý tập tin liên quan đến với C thời gian chạy tập tin mô tả
  • _open_osfhandle hiện: Cao đẳng C thời gian chạy bộ mô tả tập tin với một hiện hệ điều hành xử lý tập tin.

Hình như những gì bạn cần là _open_osfhandle tiếp theo _fdopen để có được một FILE* từ một HANDLE.

Dưới đây là ví dụ liên quan đến HANDLE s thu được từ CreateFile(). Khi tôi thử nghiệm nó, nó cho thấy 255 ký tự đầu tiên của tệp "test.txt" và nối thêm "--- Hello World! ---" ở cuối tệp:

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

Điều này sẽ làm việc cho đường ống là tốt.

Các vấn đề liên quan