2009-01-24 28 views
14

Có cách nào để tận dụng lợi thế của các cờ tạo tệp trong API Win32 như FILE_FLAG_DELETE_ON_CLOSE hoặc FILE_FLAG_WRITE_THROUGH như được mô tả ở đây http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx, nhưng sau đó buộc xử lý thành một tiêu chuẩn :: của luồng?Tôi có thể sử dụng CreateFile, nhưng buộc xử lý thành một std :: ofstream?

Giao diện tới tận gốc rõ ràng là nền tảng độc lập; Tôi muốn ép buộc một số cài đặt phụ thuộc vào nền tảng trong 'dưới mui xe' như trước đây.

Trả lời

24

Có thể đính kèm C++ std::ofstream vào bộ xử lý tệp Windows. Các mã sau đây làm việc trong VS2008:

HANDLE file_handle = CreateFile(
    file_name, GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS, 
    FILE_ATTRIBUTE_NORMAL, NULL); 

if (file_handle != INVALID_HANDLE_VALUE) { 
    int file_descriptor = _open_osfhandle((intptr_t)file_handle, 0); 

    if (file_descriptor != -1) { 
     FILE* file = _fdopen(file_descriptor, "w"); 

     if (file != NULL) { 
      std::ofstream stream(file); 

      stream << "Hello World\n"; 

      // Closes stream, file, file_descriptor, and file_handle. 
      stream.close(); 

      file = NULL; 
      file_descriptor = -1; 
      file_handle = INVALID_HANDLE_VALUE; 
     } 
} 

này làm việc với FILE_FLAG_DELETE_ON_CLOSE, nhưng FILE_FLAG_WRITE_THROUGH có thể không có hiệu quả mong muốn, như dữ liệu sẽ được đệm bởi các đối tượng std::ofstream, và không được ghi trực tiếp vào đĩa. Tuy nhiên, bất kỳ dữ liệu nào trong bộ đệm sẽ được chuyển sang hệ điều hành khi gọi là stream.close().

+0

Tuyệt vời (cũng hoạt động trong VS2005)! Một kịch bản mà tôi có là để viết một số thông tin kế toán cho một tập tin trên một USB với ghi thông qua. Bởi vì nó sẽ là một trình tự mở-viết-đóng nhanh chóng, nên việc đóng để đảm bảo bộ đệm của luồng được xả vào hệ điều hành, đúng không? –

+0

Có. Tôi đã cập nhật câu trả lời để đề cập đến điều này. – ChrisN

+0

Bất kỳ ý tưởng nào về cách thực hiện tương tự cho 'fstream' thay vì' ofstream'? – sorin

1

Một số trong những lá cờ cũng có sẵn khi sử dụng _fsopen/fopen:

FILE* pLockFile = _fsopen(tmpfilename.c_str(), "w", _SH_DENYWR); 
if (pLockFile!=NULL 
{ 
    // Write lock aquired 
    ofstream fs(pLockFile); 
} 

Ở đây chúng ta mở file nên khi làm một tuôn ra, sau đó nó viết qua (Và nó sẽ bị xóa khi đóng):

FILE* pCommitFile = fopen(tmpfilename.c_str(), "wcD"); 
if (pCommitFile!=NULL) 
{ 
    // Commits when doing flush 
    ofstream fs(pCommitFile); 
} 
Các vấn đề liên quan