2012-03-27 34 views
7

Tôi đang cố gắng ghi lại các hành động được thực hiện bởi dịch vụ tôi đã viết bằng ngôn ngữ C-Windows & C, vì vậy tôi đã tạo một hệ thống tệp nhật ký.CreateFile luôn ghi đè lên tập tin được chỉ định

Vấn đề là tại mỗi cuộc gọi CreateFile, tệp được ghi đè thay vì chỉ mở tệp và ghi vào cuối tệp.

Dưới đây là đoạn code của chức năng WriteInLogfile tôi:

void WriteInLogFile(LPCTSTR log_string) 
{ 
    HANDLE hFile; 
    DWORD dBytesWritten; 

    if ((hFile = CreateFile(LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, 
          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE 
     && (GetLastError() == ERROR_FILE_NOT_FOUND)) 
    { 
     if ((hFile = CreateFile(LOG_FILE_PATH, GENERIC_WRITE, 0, NULL, 
           CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) 
     { 
      if (!WriteFile(hFile, log_string, strlen(log_string), &dBytesWritten, NULL)) 
       aff_error("WriteInLogFile"); 
      CloseHandle(hFile); 
     } 
    } 
    else 
    { 
     if (!WriteFile(hFile, log_string, strlen(log_string), &dBytesWritten, NULL)) 
      aff_error("WriteInLogFile"); 
     CloseHandle(hFile); 
    } 
} 

Đừng ai biết nơi vấn đề xuất phát từ đâu?

cám ơn;)

+0

Nhân tiện, bạn có thể đơn giản hóa mã này bằng cách sử dụng 'OPEN_ALWAYS', thông báo cho' CreateFile' để mở tệp nếu nó tồn tại hoặc tạo tệp nếu không. Sau đó, bạn sẽ không phải sao chép quá nhiều mã của bạn. –

Trả lời

6

Mặc dù bạn đang mở tệp hiện có mà bạn không chỉ định rằng bạn muốn thêm vào tệp đó. Do đó nó mở ra như là một viết chung chung và bạn sẽ ghi đè lên các nội dung. Bạn cần phải vượt qua cờ FILE_APPEND_DATA theo phương thức CreateFile. Này được thực hiện tốt nhất bằng cách sử dụng lá cờ FILE_GENERIC_WRITE trong đó bao gồm FILE_APPEND_DATA

if ((hFile = CreateFile(LOG_FILE_PATH, FILE_GENERIC_WRITE, 0, NULL, 
          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE 
     && (GetLastError() == ERROR_FILE_NOT_FOUND)) 
    { 
+0

Điều này hoạt động tốt. Bạn có biết nếu có một cách để giữ cho dòng mới với điều này? Dường như nó bỏ qua của tôi ... –

+0

@tsabz dòng mới không nên thay đổi nếu bạn sử dụng cờ này. Bạn đang gặp sự cố khi viết chúng ra? Bạn có thể cần thêm chúng theo cách thủ công vì chính 'WriteFile' sẽ không thêm chúng cho bạn. – JaredPar

+0

Tôi gọi hàm này như sau: 'WriteInLogFile (" LOG: somethingtowrite \ n ");' và nó không giữ dòng mới. –

1

Bạn cần phải đặt con trỏ tập tin đến cuối của tập tin trước khi viết với SetFilePointer. Xem MSDN example.

1

Tôi không thể thấy bất kỳ điều gì rõ ràng về việc mở cho Nối trong tài liệu CreateFile, nhưng bạn có thể sử dụng chức năng SetFilePointer để tìm đến cuối tệp trước khi viết.

2

Khi bạn mở một tập tin, con trỏ sẽ luôn luôn được đặt ở đầu file. Để nối thêm, bạn cần tìm cách kết thúc một cách rõ ràng (SetFilePointer(hFile, 0, 0, FILE_END);).

Mặc dù nó có thể không gây ra vấn đề thực tế của bạn, tôi sẽ thay thế logic hiện tại của bạn đang cố gắng sử dụng CreateFile với OPEN_EXSTING, sau đó với CREATE_NEW nếu lần thử đầu tiên không thành công. Thay vào đó, chỉ cần vượt qua cờ OPEN_ALWAYS, mà tự động hóa khá nhiều logic đó - mở một tệp hiện có nếu nó tồn tại và tạo một tệp mới nếu không.

+0

Cảm ơn bạn, tôi đã trộn lẫn câu trả lời của bạn với câu trả lời của JaredPar và tất cả sẽ tốt hơn bây giờ :) –

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