2013-04-28 40 views
5

Câu hỏi này: How to protect log from application crash? đã dẫn tôi đến nơi khác - những gì hiện std::ofstream::close() thực sự làm gì? Tôi biết nó gọi là flush() và đó là một điều. Nhưng còn gì nữa? Những gì đóng tập tin thực sự là?std :: ofstream :: close() thực sự làm gì?

Edit: Hãy để tôi nói lại câu hỏi của tôi - được bất cứ điều gì về thể chất làm trong một file thực tế trong suốt cuộc gọi đến close() hoặc là nó chỉ std::ofstream nội thứ dọn dẹp?

Trả lời

3

Ngoài đỏ bừng bộ đệm userspace, ví dụ: flush(), close(2) được gọi là trên cơ bản tập tin mô tả. Nó phụ thuộc vào hệ điều hành những gì xảy ra sau đó, nhưng hầu như không có gì xảy ra với lưu trữ thực sự bị chiếm đóng bởi tệp.

Điều gì sẽ xảy ra là (nếu trình mô tả tệp là tham chiếu cuối cùng trong quá trình đó đối với tệp đó) mục nhập tệp được liên kết với tệp sẽ bị xóa khỏi bảng tệp mở của quy trình. I E. giải phóng bộ nhớ hạt nhân liên quan đến quá trình.

1

Đóng tệp hiện được liên kết với đối tượng, hủy liên kết tệp khỏi luồng.

Mọi chuỗi đầu ra đang chờ xử lý được ghi vào tệp.

Nếu luồng hiện không được liên kết với bất kỳ tệp nào (tức là, không có tệp nào được mở thành công), việc gọi hàm này không thành công.

Kết hợp tệp của luồng được giữ bởi bộ đệm luồng nội bộ: Nội bộ, hàm gọi rdbuf() -> close() và đặt failbit trong trường hợp lỗi.

Lưu ý rằng bất kỳ tệp đang mở nào sẽ tự động đóng khi đối tượng ofstream bị hủy.

Từ: http://www.cplusplus.com/reference/fstream/ofstream/close/

+0

Tôi đã lặp lại câu hỏi của mình, vui lòng xem bản chỉnh sửa của bài đăng gốc. – NPS

3

Đây là dấu vết của các cuộc gọi từ tài liệu:


void std::basic_ofstream::close(); 

hiệu quả gọi rdbuf()->close(). Nếu xảy ra lỗi trong khi hoạt động, hãy gọi setstate(failbit).


std::basic_streambuf<CharT,Traits>* std::basic_ofstream::rdbuf() const; 

Trả về đệm dòng liên quan. Nếu không có bộ đệm luồng liên quan, trả về NULL.


std::basic_streambuf thực sự thừa hưởng std::basic_filebuf, do đó:


std::basic_filebuf<CharT, Traits>* std::basic_filebuf::close(); 

Nếu một khu vực đặt tồn tại (ví dụ như tập tin đã được mở ra cho văn bản), các cuộc gọi đầu tiên overflow(Traits::eof()) để viết tất cả các đầu ra cấp phát đến tập tin, bao gồm bất kỳ trình tự unshift nào.

Nếu thời gian gần đây được gọi là hầu hết các chức năng, trong số underflow(), overflow(), seekpos(), và seekoff(), là overflow(), sau đó gọi std::codecvt::unshift(), có lẽ nhiều lần, để xác định trình tự unshift theo locale thấm nhuần, và viết rằng chuỗi nộp với overflow(Traits::eof()).

Sau đó, đóng tệp như thể bằng cách gọi std::fclose, bất kể có bất kỳ cuộc gọi nào trước đó đã thành công hay không thành công.

LƯU Ý:.close() thường được gọi là thông qua các destructor của std::basic_filebuf (trong đó, lần lượt, thường được gọi bằng destructor của std::basic_fstream


Trước hết, chúng ta có thể thấy rằng nó doesn' t thực sự gọi trực tiếp flush() như bạn mong đợi, tuy nhiên, hiệu ứng đỏ bừng thực sự xảy ra theo phương pháp std::basic_filebuf::close(). Ngoài ra, chúng ta có thể thấy rằng nó vẫn làm xáo trộn một tệp, ví dụ như viết trình tự unshift. xảy ra sau đó, tệp đơn giản đóng.

Chú ý đến LƯU Ý ở trên: trong hầu hết các trường hợp, bạn thậm chí không cần gọi số std::basic_ofstream::close() một cách rõ ràng.

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