Sự khác biệt giữa java.io.PrintWriter và java.io.BufferedWriter?


94

Vui lòng xem qua mã bên dưới:

// A.class
File file = new File("blah.txt");
FileWriter fileWriter = new FileWriter(file);
PrintWriter printWriter = new PrintWriter(fileWriter);

// B.class
File file = new File("blah.txt");
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bWriter = new BufferedWriter(fileWriter);

Sự khác biệt giữa hai phương pháp này là gì?

Khi nào chúng ta nên sử dụng PrintWriter trên BufferedWriter?

Câu trả lời:


61

Tham chiếu API cho BufferedWriterPrintWriter nêu chi tiết sự khác biệt.

Lý do chính để sử dụng PrintWriter là để truy cập vào các phương thức printXXX như println (). Về cơ bản, bạn có thể sử dụng PrintWriter để ghi vào tệp giống như bạn sử dụng System.out để ghi vào bảng điều khiển.

BufferedWriter là một cách hiệu quả để ghi vào một tệp (hoặc bất kỳ thứ gì khác), vì nó sẽ đệm các ký tự trong bộ nhớ Java trước đó (có thể, tùy thuộc vào việc triển khai) thả xuống C để thực hiện việc ghi vào tệp.

Không có khái niệm như "PrintReader"; gần nhất bạn sẽ nhận được có lẽ là java.util.Scanner .


4
@TritonMan tại một số thời điểm nó cần phải tương tác với hệ điều hành, có nghĩa là bước ra ngoài Java.
TofuBeer

89

PrintWritercung cấp nhiều phương thức hơn ( println), nhưng sự khác biệt quan trọng nhất (và đáng lo ngại) cần biết là nó nuốt các ngoại lệ .

Bạn có thể gọi lại checkErrorsau để xem có lỗi nào xảy ra hay không, nhưng thông thường bạn sẽ sử dụng PrintWritercho những việc như ghi vào bảng điều khiển - hoặc trong các ứng dụng "nhanh chóng" nơi bạn không muốn bị làm phiền bởi các ngoại lệ (và ở đâu độ tin cậy lâu dài không phải là một vấn đề).

Tôi không chắc tại sao các khía cạnh "khả năng định dạng bổ sung" và "không nuốt ngoại lệ" được gộp chung vào cùng một lớp - định dạng rõ ràng là hữu ích ở nhiều nơi mà bạn không muốn ngoại lệ bị nuốt. Sẽ thật tuyệt nếu BufferedWritermột lúc nào đó có được những khả năng tương tự ...


@WindyFields: Không, PrintStreamlà một OutputStream. PrintWriterlà một Writer.
Jon Skeet

Cảm ơn. "nó nuốt chửng những trường hợp ngoại lệ." Ý bạn là PrintWriter không nêu ra các ngoại lệ đã kiểm tra? Làm thế nào về các ngoại lệ không được kiểm tra?

@Ben: Tôi đã nói cụ thể về vấn đề đó IOException, mọi sự trừu tượng IO khác ( Reader, Writerv.v.) đều khai báo rằng các phương thức của nó sẽ ném IOExceptionnếu có sự cố - PrintWriterkhông.
Jon Skeet

8

Như đã nói trong câu trả lời của TofuBeer, cả hai đều có điểm đặc biệt của họ. Để tận dụng toàn bộ lợi thế của PrintWriter (hoặc bất kỳ trình viết nào khác) nhưng cũng sử dụng tính năng ghi có đệm, bạn có thể bọc BufferedWriter bằng một thứ cần thiết như sau:

PrintWriter writer = new PrintWriter(
                         new BufferedWriter (
                             new FileWriter("somFile.txt")));

2
Ghi nhớ @Jons nhận xét rằng PrintWriter sẽ nuốt các ngoại lệ. checkError sẽ được gọi.
MadMurf

1
Tôi yêu các tenenbaums hoàng gia
Ogen

4
Ít nhất trong triển khai openJDK 8 hiện tại (và có thể là các phiên bản cũ hơn), PrinterWriterđã tạo ra một BufferedWriter.
nimrodm

7

PrintWriter chỉ hiển thị các phương thức in trên bất kỳ Writer nào ở chế độ ký tự.

BufferedWriter hiệu quả hơn, theo các phương thức được đệm của nó. Và nó đi kèm với một phương thức newLine (), tùy thuộc vào nền tảng hệ thống của bạn, để thao tác các tệp văn bản một cách chính xác.

BufferedReader cho phép đọc một văn bản từ tệp, với các byte được chuyển đổi thành ký tự. Nó cho phép đọc từng dòng.

Không có PrintReader, bạn phải chọn triển khai Reader khác theo định dạng đầu vào của bạn.


3

PrintWriter là phần mềm Writer nâng cao nhất để ghi dữ liệu Ký tự vào một tệp.

Ưu điểm chính của PrintWriter so với FileWriter và BufferedWriter là:

  1. PrintWriter có thể giao tiếp trực tiếp với tệp và cũng có thể giao tiếp thông qua một số đối tượng Writer.

PrintWriter printwriter = new PrintWriter("blah.txt");

(hoặc là)

FileWriter filewriter = new FileWriter("blah.txt");
PrintWriter printwiter = new PrintWriter(filewriter);
  1. Chúng ta có thể ghi trực tiếp bất kỳ loại dữ liệu Nguyên thủy nào vào tệp (vì chúng ta có các phiên bản nạp chồng bổ sung của các phương thức PrintWriter, tức là print () và println ()).

    printwriter.print(65); //65
    bufferedwriter.write(65); //A
    printwriter.println(true); //true


2

Nói chung, một Writer gửi đầu ra của nó ngay lập tức đến ký tự bên dưới hoặc luồng byte. Trừ khi yêu cầu đầu ra nhanh chóng, bạn nên quấn một BufferedWriter xung quanh bất kỳ Writer nào mà các hoạt động write () có thể tốn kém, chẳng hạn như FileWriters và OutputStreamWriters. Ví dụ,

Lưu ý: Nội dung văn bản trong các khối mã được tự động gói từ

PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

sẽ đệm đầu ra của PrintWriter vào tệp. Nếu không có bộ đệm, mỗi lệnh gọi phương thức print () sẽ khiến các ký tự được chuyển đổi thành các byte sau đó sẽ được ghi ngay vào tệp, điều này có thể rất kém hiệu quả.


0

BufferedWriter - Ghi văn bản vào một luồng ký tự đầu ra, đệm các ký tự từ một luồng ký tự. PrintWriter - In các biểu diễn được định dạng của các đối tượng vào một luồng đầu ra văn bản.


-1

Tôi nghĩ rằng lý do đằng sau việc sử dụng PrintWriter đã được đề cập ở trên nhưng một trong những lý do quan trọng là bạn chuyển một đối tượng tệp trực tiếp đến phương thức khởi tạo PrintWriter để giúp bạn dễ dàng sử dụng nó.

File file=new File(“newfile.txt”);
PrintWriter pw=new PrintWriter(file);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.