Giải pháp tốt nhất là thực hiện viết không đồng bộ với bộ đệm đôi.
Nhìn vào dòng thời gian:
------------------------------------------------>
FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|
'F' biểu thị thời gian để điền vào bộ đệm và 'W' biểu thị thời gian ghi bộ đệm vào đĩa. Vì vậy, vấn đề lãng phí thời gian giữa việc viết bộ đệm vào tập tin. Tuy nhiên, bằng cách thực hiện viết trên một luồng riêng biệt, bạn có thể bắt đầu điền vào bộ đệm tiếp theo ngay sau đây:
------------------------------------------------> (main thread, fills buffers)
FF|ff______|FF______|ff______|________|
------------------------------------------------> (writer thread)
|WWWWWWWW|wwwwwwww|WWWWWWWW|wwwwwwww|
F - điền vào bộ đệm thứ nhất
f - điền vào bộ đệm thứ 2
W - ghi bộ đệm thứ nhất vào tệp
w - ghi bộ đệm thứ 2 vào tệp
_ - chờ trong khi thao tác hoàn tất
Cách tiếp cận này với hoán đổi bộ đệm rất hữu ích khi điền vào bộ đệm đòi hỏi tính toán phức tạp hơn (do đó, mất nhiều thời gian hơn). Tôi luôn triển khai lớp CSequentialStreamWriter ẩn cách viết không đồng bộ bên trong, vì vậy đối với người dùng cuối, giao diện chỉ có (các) chức năng Viết.
Và kích thước bộ đệm phải là bội số của kích thước cụm đĩa. Nếu không, bạn sẽ kết thúc với hiệu suất kém bằng cách ghi một bộ đệm vào 2 cụm đĩa liền kề.
Viết bộ đệm cuối cùng.
Khi bạn gọi hàm Write lần cuối, bạn phải chắc chắn rằng bộ đệm hiện tại đang được điền cũng nên được ghi vào đĩa. Do đó, CSequentialStreamWriter nên có một phương thức riêng, giả sử Finalize (bộ đệm cuối cùng), ghi vào đĩa cuối cùng của dữ liệu.
Xử lý lỗi.
Trong khi mã bắt đầu điền vào bộ đệm thứ 2 và mã thứ nhất đang được viết trên một luồng riêng biệt, nhưng viết không thành công vì một số lý do, luồng chính phải nhận thức được sự thất bại đó.
------------------------------------------------> (main thread, fills buffers)
FF|fX|
------------------------------------------------> (writer thread)
__|X|
Giả sử giao diện của CSequentialStreamWriter có hàm Write trả về bool hoặc ném một ngoại lệ, do đó có lỗi trên một luồng riêng biệt, bạn phải nhớ trạng thái đó, vì vậy, lần tới khi bạn gọi Write hoặc Finilize trên luồng chính, phương thức sẽ trả về Sai hoặc sẽ ném một ngoại lệ. Và việc bạn dừng điền bộ đệm vào thời điểm nào không quan trọng, ngay cả khi bạn đã viết một số dữ liệu trước khi thất bại - rất có thể tệp sẽ bị hỏng và vô dụng.