2012-11-05 14 views
5

Mam metodę, która akceptuje InputStream (danych binarnych) i serializuje go do XML. Aby to zrobić, zawija strumień za pomocą kodera base64 i Reader, aby przekształcić go w dane postaci. Ponieważ jednak parametr InputStream jest przekazywany jako parametr, uznam za szkodliwy efekt uboczny zamknięcie strumienia, a umowa o Reader.close() mówi, że tak właśnie by się stało. Jeśli nie zamknąć czytnik, kompilator ostrzega mnie, że mam wyciekCzy można zamknąć czytnik bez zamykania strumienia?

zasobów: czytelnik nigdy nie jest zamknięta

Więc mogę dodać @SuppressWarnings("resource") do deklaracji czytelnika, ale jest co należy zrobić? Czy czegoś brakuje?

Oto rzeczywisty kod:

/** 
* 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

Jaki jest Twój cel chcąc utrzymać Stream otwarte? Możesz go ponownie otworzyć w dowolnym momencie. – mabako

+0

Czy istnieje sposób na zmianę kodu w celu utworzenia jednego Czytnika dla InputStream i przekazanie go metodom wymagającym czytnika Reader? Tak czy inaczej, czytnik i strumień wejściowy powinny być zamknięte razem. –

+0

@mabako, to nie jest tak naprawdę pragnienie, aby utrzymać otwarty strumień, a tym bardziej odpowiedzialność. Próbuję zamknąć wszystko, gdzie jest otwarte. Jeśli metoda binarna zamknie strumień, a coś poza tym połączeniem spróbuje coś z nim zrobić, może to być spowodowane przez wyjątek, którego użytkownik się nie spodziewał. – Lucas

Odpowiedz

1

Jeżeli jesteś zadowolony Java 7 użytkownik, spróbuj tego:

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

i strumień jest zamknięty dla Ciebie. Jeśli nie możesz używać Javy 7, zgadzam się, że to nie jest odpowiedzialność za strumień. Po prostu zignoruj ​​ostrzeżenie i nie pozwól narzędziom napędzać twojego projektu. W porządku.

W ostateczności możesz napisać lekką opaskę Reader ignorującą close(), ale nie radzę jej, ponieważ utrudnia ona przepływ programu.

niech także Apache Commons IO pomóc 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

Nie rozumiem twojego pierwszego segmentu, ponieważ pokazuje on tylko to, co aktualnie robię, to znaczy zamyka 'InputStream' w wywołującej metodę binarną, a nie w samej metodzie. Używam java 6, ale po prostu kończę w końcu w bloku. Mógłbym napisać opakowanie, tak, ale to wydaje się mniej poprawne niż '@SuppressWarnings (" resource ")'.Dobra sugestia na temat IOUtils, zwykle robię takie rzeczy, tylko że jest to biblioteka niskiego poziomu i chciałem jak najmniej zależności. – Lucas

+0

@Lucas: masz rację, pierwsza część mojej odpowiedzi po prostu powtarza twoje podejście - które uznałem za prawidłowe. Zauważ, że biblioteka 'IOUtils.copy()' również nie zamyka 'Reader' po skopiowaniu. Chcę tylko powiedzieć: to narzędzie jest złe, nie ty. –

0

Jest to być może „funkcja” w pracach sposób Base64InputStream że nawet jeśli określić długość czytać, będzie zamknąć podstawowy strumień jeśli go zamknąć kiedy wyraźnie nie chciałeś czytać całego strumienia.

Można zawinąć strumień binaryStream w obiekcie InputStream, który ignoruje zamknięcie, lub można pominąć ostrzeżenie, tak jak to zostało zrobione.

+0

Dobra sugestia na opakowaniu, ale wydaje się to mniej poprawne niż '@SuppressWarnings (" resource ")'. – Lucas

Powiązane problemy