2013-07-08 31 views
7

Tôi đã luôn sử dụng FileWriter để viết văn bản vào một tệp bằng Java. Rõ ràng bạn cũng có thể sử dụng một số BufferedOutputStream. Sau khi đọc kỹ cả javadocs, tôi dường như không thể biết được cái nào nhanh hơn/hiệu quả hơn.Hiệu suất: BufferedOutputStream vs FileWriter

Vì vậy, tôi hỏi: có sự khác biệt về hiệu suất (ngay cả khi tối thiểu) giữa hai phương pháp I/O tệp này không? Nếu vậy, chúng là gì và tại sao? Nếu không, tại sao chúng lại có hiệu quả như nhau?

Có tình huống nào được ưu tiên hơn trường hợp khác không? Cảm ơn trước!

Trả lời

9

Nếu bạn thực sự muốn so sánh FileWriter với BufferedOutputStream để viết tệp văn bản, tệp sau phải nhanh hơn vì có ít hoạt động I/O hơn.

  • Trong trường hợp FileWriter, mỗi cuộc gọi đến phương thức ghi sẽ được duy trì cùng một lúc (không bị chặn).
  • Trong trường hợp của BufferedOutputStream, dữ liệu sẽ được ghi vào đĩa, nếu bộ đệm đầy (hoặc bộ đệm được giải phóng bằng phương pháp flush).

Nhưng nếu bạn viết các file văn bản, bạn nên sử dụng một Writer; trong trường hợp này chúng ta có thể so sánh với một FileWriterBufferedWriter:

Nhìn vào

FileWriter fw = new FileWriter(...) 

BufferedWriter bw = new BufferedWriter(new FileWriter(...) 

bạn có hoàn cảnh tương tự về số/O hoạt động.


A FileWriter sử dụng FileOutputStream nội bộ. Lý do để sử dụng một FileWriter là nó tự động sử dụng mã hóa ký tự mặc định, khi bạn ghi vào một tệp (một chuỗi nội bộ Java được mã hóa thành UTF-8 chẳng hạn).Nếu bạn sử dụng một OutputStream, bạn phải mã hóa bằng tay trong từng viết:

Vì vậy, ví dụ này cho một BufferedWriter:

bw.write("Hello"); 

tương ứng với ví dụ rằng đối với một BufferedOutputStream:

bos.write("Hello".getBytes(Charset.forName("utf-8"))); 

nếu bạn mã hóa mặc định là utf-8.

An OutputStream giao dịch với (nguyên) byte trong khi một giao dịch với ký tự (văn bản).

2

Một FileWriter viết văn bản-file, trong khi một BufferedOutputStream giữ một bộ đệm dữ liệu nhị phân tùy ý trong bộ nhớ trước khi ghi nó vào một dòng nhị phân mà bạn phải cung cấp. Họ không làm điều tương tự ở tất cả, vì vậy so sánh hiệu suất của họ là vô nghĩa.

Nói chung, bộ đệm cải thiện thông lượng ứng dụng nhưng thêm độ trễ. Trong trường hợp tệp, bạn có thể tạo ra nhiều đầu ra hơn mỗi giây vì bạn có thể chuyển các khối lớn hơn vào đĩa cùng một lúc, do đó, chi phí trên mỗi byte thấp hơn. Mặt khác, trong khi dữ liệu đang được đệm trong bộ nhớ nó không được ghi vào đĩa, vì vậy phải mất một thời gian lâu hơn cho bất kỳ byte cụ thể để có được ghi vào đĩa.

Trong trường hợp FileWriter, nó đã có bộ đệm trong giúp mã hóa ký tự thành byte. Thêm nhiều bộ đệm có thể có ít giá trị.

+0

Cảm ơn @Joni (+1) - quan sát thú vị, nhưng bạn có thể * không * ghi văn bản vào tệp bằng 'BufferedOutputStream'?!? [Bài viết này] (http://www.javadb.com/write-to-file-using-bufferedoutputstream) dường như nghĩ khác đi. Nếu bài viết đó là đúng, thì mặc dù 'FileWriter' và' BufferedOutputStream' có thể dùng cho 2 mục đích khác nhau, nó là * possible (và do đó là điểm của câu hỏi của tôi) để so sánh hiệu suất của chúng khi viết văn bản vào một tập tin. –

+0

Một lần nữa, nội dung thú vị @Joni! Theo [câu hỏi SO này] (http://stackoverflow.com/questions/6108043/java-does-filewriter-use-a-buffer-it-acts-like-it-does-in-my-example) có vẻ như có thể ghi đè bộ đệm bên trong mà 'FileWriter' sử dụng. Tôi muốn thử điều này, nếu không có gì khác, vì sự thích thú cá nhân của riêng tôi. Đối với cuộc sống của tôi, tôi không thể tìm ra cách cấu hình 'OutputStreamWriter' và' FileOutputStream' và tiêm chúng vào một hàm tạo 'FileWriter' - bất kỳ ý tưởng nào? Và tôi sẽ chỉ định kích thước bộ đệm mới ở đâu? Cảm ơn bạn một lần nữa vì đã giúp đỡ rất nhiều! –

+0

Như bạn có thể thấy trong bài báo, để viết văn bản với một 'BufferedOutputStream' đầu tiên họ đã chuyển đổi bất kỳ văn bản nào thành byte theo cách thủ công, bằng cách lấy' getBytes', không thuận tiện và tạo ra một mảng các byte trở thành rác ngay lập tức – Joni

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