2012-11-05 36 views
5

Tôi có phương thức chấp nhận InputStream (dữ liệu nhị phân) và tuần tự hóa nó thành XML. Để làm như vậy, nó kết thúc tốt đẹp luồng bằng bộ mã hóa base64 và Reader để chuyển đổi nó thành dữ liệu ký tự. Tuy nhiên, kể từ khi InputStream được chuyển thành tham số, tôi sẽ coi đó là một tác dụng phụ có hại để đóng luồng và hợp đồng cho Reader.close() cho biết sẽ thực hiện điều đó. Nếu tôi không đóng reader, trình biên dịch cảnh báo với tôi rằng tôi có một sự rò rỉCó thể đóng Trình đọc mà không đóng luồng không?

Resource: đọc không bao giờ đóng

Vì vậy, tôi có thể thêm một @SuppressWarnings("resource") để tuyên bố độc giả, nhưng là điều đúng đắn phải làm là gì? Tui bỏ lỡ điều gì vậy?

Đây là mã thực tế:

/** 
* Writes base64 encoded text read from the binary stream. 
* 
* @param binaryStream 
*   The binary stream to write from 
* @return <code>this</code> XmlWriter (for chaining) 
* @throws IOException 
*/ 
public XmlWriter binary(InputStream binaryStream) throws IOException { 
    Reader reader = new InputStreamReader( 
      new Base64InputStream(binaryStream, true, base64LineLength, base64LineSeparator.getBytes(charset))); 
    int bufferSize = 2048; 
    int charsRead; 
    char[] buffer = new char[bufferSize]; 
    while ((charsRead = reader.read(buffer, 0, bufferSize)) >= 0) { 
     writer.write(buffer, 0, charsRead); 
    } 

    return this; 
} 
+0

mục đích của bạn vì muốn giữ Stream mở là gì? Bạn chỉ có thể mở lại bất kỳ lúc nào. – mabako

+0

Ngoài ra, có cách nào để bạn có thể thay đổi mã của mình để tạo một Reader cho InputStream và chuyển nó tới các phương thức cần Reader không? Bằng cách này hay cách khác, Reader và luồng đầu vào phải được đóng lại với nhau. –

+0

@mabako, nó không thực sự là một mong muốn để giữ cho dòng mở, nhiều hơn của một trách nhiệm điều. Tôi cố gắng đóng mọi thứ nơi nó được mở ra. Nếu phương thức nhị phân đóng luồng và một cái gì đó bên ngoài cuộc gọi này cố gắng làm điều gì đó với nó, nó có thể thông qua một ngoại lệ mà người dùng không mong đợi. – Lucas

Trả lời

1

Nếu bạn là một người hạnh phúc Java 7 người dùng, hãy thử này:

try(InputStream binaryStream = /* ... */) { 
    xmlWriter.binary(binaryStream); 
} 

và dòng được đóng cửa cho bạn. Nếu bạn không thể sử dụng Java 7, tôi đồng ý rằng đó không phải là trách nhiệm của phương pháp binary() đối với close() luồng. Chỉ cần bỏ qua cảnh báo và không cho phép các công cụ thúc đẩy thiết kế của bạn. Tốt rồi.

Như một phương sách cuối cùng, bạn có thể viết một wrapper nhẹ Reader bỏ qua close(), nhưng tôi không khuyên nó vì nó làm cho dòng chảy chương trình khó khăn hơn.

Cũng cho Apache Commons IO giúp bạn với IOUtils.copy():

public XmlWriter binary(InputStream binaryStream) throws IOException { 
    Reader reader = new InputStreamReader( 
      new Base64InputStream(binaryStream, true, base64LineLength, base64LineSeparator.getBytes(charset))); 
    IOUtils.copy(reader, writer); 
    return this; 
} 
+0

Tôi không hiểu phân đoạn đầu tiên của bạn vì nó chỉ hiển thị những gì tôi hiện đang làm, đó là để nói, đóng 'InputStream' trong người gọi của phương thức nhị phân, không phải trong chính phương thức đó. Tôi sử dụng java 6, nhưng chỉ có đóng trong một khối cuối cùng. Tôi có thể viết một wrapper, có, nhưng điều đó có vẻ ít chính xác hơn '@SuppressWarnings (" tài nguyên ")'.Đề xuất tốt về IOUtils, tôi thường làm những việc như thế, chỉ rằng đây là thư viện cấp thấp và tôi muốn càng ít phụ thuộc càng tốt. – Lucas

+0

@Lucas: bạn nói đúng, phần đầu tiên của câu trả lời của tôi chỉ nhắc lại cách tiếp cận của bạn - mà tôi thấy chính xác. Lưu ý rằng thư viện 'IOUtils.copy()' cũng không đóng 'Reader' sau khi sao chép nó. Tôi chỉ muốn nói: đó là công cụ sai, không phải bạn. –

0

Đây là một có lẽ là một "tính năng" trong công tác cách Base64InputStream rằng mặc dù bạn chỉ định độ dài để đọc, nó sẽ đóng dòng cơ bản nếu bạn đóng nó khi rõ ràng bạn dự định không đọc toàn bộ luồng.

Bạn có thể bao bọc binaryStream trong InputStream để bỏ qua hoặc bạn có thể chặn cảnh báo như bạn có.

+0

Đề xuất tốt về trình bao bọc, nhưng điều đó có vẻ kém chính xác hơn '@SuppressWarnings (" tài nguyên ")'. – Lucas

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