Bài viết của Tim Bray "Saving Data Safely" để lại cho tôi các câu hỏi mở. Hôm nay, nó đã hơn một tháng tuổi và tôi đã không thấy bất kỳ sự theo dõi nào, vì vậy tôi đã quyết định giải quyết vấn đề ở đây.tình huống ext4/fsync không rõ ràng trong Android (Java)
Một điểm của bài viết là FileDescriptor.sync() nên được gọi là an toàn khi sử dụng FileOutputStream. Lúc đầu, tôi đã rất khó chịu, bởi vì tôi chưa bao giờ thấy bất kỳ mã Java nào thực hiện đồng bộ trong suốt 12 năm tôi làm Java. Đặc biệt là khi đối phó với các tập tin là một điều khá cơ bản. Ngoài ra, JavaDoc chuẩn của FileOutputStream không bao giờ ám chỉ đồng bộ hóa (Java 1.0 - 6). Sau một số nghiên cứu, tôi đã tìm ra ext4 thực sự có thể là hệ thống tập tin chính thống đầu tiên cần đồng bộ hóa. (Có hệ thống tập tin khác, nơi đồng bộ rõ ràng được khuyên?)
Tôi đánh giá cao một vài suy nghĩ chung về vấn đề này, nhưng tôi cũng có một số câu hỏi cụ thể:
- Khi Android sẽ làm đồng bộ với hệ thống tập tin ? Điều này có thể định kỳ và bổ sung dựa trên các sự kiện vòng đời (ví dụ: quy trình của ứng dụng sẽ chuyển sang nền sau).
- FileDescriptor.sync() có chăm sóc đồng bộ hóa dữ liệu meta không? Đó là đồng bộ thư mục của tập tin đã thay đổi. So sánh với FileChannel.force().
- Thông thường, một người không trực tiếp ghi vào FileOutputStream. Đây là giải pháp của tôi (bạn có đồng ý không?):
FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE); BufferedOutputStream out = new BufferedOutputStream(fileOut); try { out.write(something); out.flush(); fileOut.getFD().sync(); } finally { out.close(); }
Tôi đã dự kiến lệnh flush() để đảm bảo mọi thứ được ghi vào đĩa - về cơ bản là bằng cách gọi sync(). Đó không phải là trường hợp? –
@a_horse_with_no_name: Không, không phải. _flush_ và _sync_ là hai hoạt động khác nhau: flush chỉ xóa các bộ đệm trung gian; đồng bộ thực sự ghi vào bộ nhớ. Xem ví dụ http://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync – sleske
@sleske: cảm ơn vì đã làm rõ! –