2011-09-02 9 views
6
int main(int argc, char *argv[]) 
{ 
    FILE *fp = fopen("a.txt", "wt"); 

    fprintf(fp, "AAAA"); 

    // No flush. and No close 
    raise(SIGTERM); 

    exit(EXIT_SUCCESS); 
} 

result: No data has written to a.txtTại sao dữ liệu không được chuyển sang tệp khi thoát khỏi quá trình?

tôi mong đợi điều này là tốt. Bởi vì hệ thống sẽ đóng tập tin xử lý và sau đó trình điều khiển hệ thống tập tin xóa sạch dữ liệu chưa được lưu trong trình xử lý Đóng của bạn. Nhưng không phải vậy. Tôi đã thử nghiệm mã này trên EXT4, ubuntu 11.10

Câu hỏi: Tôi nghĩ TẤT CẢ hệ thống tập tin phải xóa dữ liệu chưa được dọn dẹp khi xử lý gần.
Posix không có quy tắc?

Tái bút Mã này làm việc tốt (đỏ mặt tốt) trên NTFS, Win7

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HANDLE h = CreateFile(L"D:\\a.txt", GENERIC_READ|GENERIC_WRITE, 
     0, 0, OPEN_ALWAYS, 0, 0); 
    BYTE a[3]; 
    memset(a, 'A', 3); 
    DWORD dw; 
    WriteFile(h, (PVOID)a, 3, &dw, 0); 

    TerminateProcess(GetCurrentProcess(), 1); 
    return 0; 
} 

Edit:
Tôi đã thử nghiệm nó một lần nữa với hệ thống gọi write. Và nó đã được rửa sạch.

int main(int argc, char** argv) 
{ 
    int fd = open("a.txt", O_CREAT|O_TRUNC|O_WRONLY); 
    char buf[3]; 
    memset(buf, 'A', 3); 
    size_t result = write(fd, buf, 3); 

    raise(SIGTERM); 
    exit(EXIT_SUCCESS); 
    return 0; 
} 

Trả lời

5

Nó không liên quan gì đến trình điều khiển hệ thống tệp. Vấn đề là CRT đang lưu trữ chính luồng tập tin. Bạn thiết lập kích thước bộ đệm với setvbuf(), nó sử dụng một mặc định nếu bạn không sử dụng chức năng này.Không có đệm trong ứng dụng khi bạn sử dụng WriteFile(), đầu ra được đệm trong bộ đệm ẩn của hệ thống tệp của hệ điều hành. Miễn dịch từ hủy bỏ ứng dụng đột ngột.

Bạn sẽ phải gọi fflush() để đạt được điều tương tự.

7

Điều này không liên quan gì đến hệ thống tệp, thay vào đó là hành vi của triển khai C bạn đang sử dụng để xác định thời điểm mở luồng bị xóa hay không.

Dưới POSIX, hành động hành động mặc định cho các tín hiệu SIGTERM là:

chấm dứt bất thường của quá trình. Quá trình này được chấm dứt với tất cả những hậu quả của _exit() ...

_exit() tương đương với _Exit() theo tiêu chuẩn C và lựa chọn xem có nên tuôn suối không được xác định bởi các tiêu chuẩn:

Các hàm _Exit() và _exit() sẽ không gọi các hàm được đăng ký với atexit() hoặc bất kỳ trình xử lý tín hiệu đã đăng ký nào. Cho dù con suối mở đang đỏ mặt hoặc đóng cửa, hoặc các tập tin tạm thời được loại bỏ là thực hiện xác định ...

Giả sử bạn đang sử dụng glibc trên Linux, từ (tôi nhấn mạnh) documentation:

Khi một quá trình chấm dứt vì bất kỳ lý do nào — vì chương trình chấm dứt hoặc do tín hiệu — những điều sau đây xảy ra:

  • Tất cả các mô tả tệp mở trong quá trình này đều bị đóng. Xem I/O mức thấp. Lưu ý rằng các luồng không được tự động xả khi quá trình chấm dứt; xem I/O trên Luồng.

Tôi không quen với WriteFileTerminateProcess vì vậy tôi không thể bình luận về những gì các hành vi ghi nhận là Windows.

+0

Cảm ơn, tôi sẽ kiểm tra lại với các cuộc gọi hệ thống, chứ không phải crt khi tôi về nhà – Benjamin