2008-08-28 27 views
5

Tôi hiện đang sử dụng chức năng sau để thực hiện một HTTP GET đơn giản.Có lý do nào để sử dụng BufferedReader trên InputStreamReader khi đọc tất cả các ký tự không?

public static String download(String url) throws java.io.IOException { 
    java.io.InputStream s = null; 
    java.io.InputStreamReader r = null; 
    //java.io.BufferedReader b = null; 
    StringBuilder content = new StringBuilder(); 
    try { 
     s = (java.io.InputStream)new URL(url).getContent(); 

     r = new java.io.InputStreamReader(s); 
     //b = new java.io.BufferedReader(r); 

     char[] buffer = new char[4*1024]; 
     int n = 0; 
     while (n >= 0) { 
      n = r.read(buffer, 0, buffer.length); 
      if (n > 0) { 
       content.append(buffer, 0, n); 
      } 
     } 
    } 
    finally { 
     //if (b != null) b.close(); 
     if (r != null) r.close(); 
     if (s != null) s.close(); 
    } 
    return content.toString(); 
} 

Tôi không thấy lý do gì để sử dụng số BufferedReader vì tôi sẽ tải xuống mọi thứ theo thứ tự. Tôi có nghĩ rằng không có sử dụng cho BufferedReader trong trường hợp này?

Trả lời

4

Trong trường hợp này, tôi sẽ làm như bạn đang làm (sử dụng một mảng byte để đệm và không phải một trong các bộ đệm luồng).

Có những ngoại lệ. Một nơi bạn nhìn thấy bộ đệm (đầu ra thời gian này) là trong API servlet. Dữ liệu không được ghi vào luồng cơ bản cho đến khi flush() được gọi, cho phép bạn tạo bộ đệm nhưng sau đó đổ bộ đệm nếu xảy ra lỗi và thay vào đó hãy viết trang lỗi. Bạn có thể đệm đầu vào nếu bạn cần đặt lại luồng để đọc lại bằng cách sử dụng dấu (int)đặt lại(). Ví dụ: có thể bạn sẽ kiểm tra tiêu đề tệp trước khi quyết định xử lý nội dung nào để truyền luồng.

Không liên quan, nhưng tôi nghĩ bạn nên viết lại quá trình xử lý luồng của mình. Mẫu này hoạt động tốt nhất để tránh rò rỉ tài nguyên:

InputStream stream = new FileInputStream("in"); 
    try { //no operations between open stream and try block 
     //work 
    } finally { //do nothing but close this one stream in the finally 
     stream.close(); 
    } 

Nếu bạn đang mở nhiều luồng, lồng thử/khối cuối cùng.

Một điều khác mà mã của bạn đang thực hiện là giả định rằng nội dung trả về được mã hóa trong bộ ký tự mặc định của máy ảo (mặc dù có thể đủ, tùy thuộc vào trường hợp sử dụng).

1

Bạn đúng, nếu bạn sử dụng BufferedReader để đọc nội dung HTTP và tiêu đề, bạn sẽ muốn InputStreamReader để bạn có thể đọc byte cho byte. Nếu bạn sử dụng InputStreamReader, bạn có thể đọc chiều dài nội dung và đọc rằng nhiều byte ...

0

Đường ruột của tôi cho tôi biết rằng vì bạn đã thực hiện đệm bằng cách sử dụng mảng byte, nên việc sử dụng BufferedReader là không cần thiết.

1

Mỗi lần gọi một phương thức read() của InputStreamReader có thể khiến một hoặc nhiều byte được đọc từ luồng đầu vào byte cơ bản. Để cho phép chuyển đổi hiệu quả các byte thành ký tự, nhiều byte hơn có thể được đọc trước từ luồng cơ bản hơn là cần thiết để đáp ứng hoạt động đọc hiện tại.

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