Apache Commons IO ma wygodną metodę IOUtils.toString () do odczytywania ciągu znakówInputStream
.
Ponieważ próbuję odejść od Apache Commons i przenieść się do Guawy : czy istnieje odpowiednik w guawie? Przejrzałem wszystkie klasy w com.google.common.io
pakiecie i nie mogłem znaleźć nic tak prostego.
Edycja: rozumiem i doceniam problemy z zestawami znaków. Tak się składa, że wiem, że wszystkie moje źródła są w ASCII (tak, ASCII, nie ANSI itp.), Więc w tym przypadku kodowanie nie jest dla mnie problemem.
java
io
inputstream
guava
Sean Patrick Floyd
źródło
źródło
Charsets.US_ASCII
), Zamiast pozwalać ci mówić "eh, jakikolwiek zgaduję?" co wielu ludziom wydaje się szczęśliwe. Zwłaszcza, że Java nie używa wartości domyślnych, które mają sens, jak UTF-8.Odpowiedzi:
W swoim komentarzu do odpowiedzi Caluma stwierdziłeś, że zamierzasz użyć
Ten kod jest problematyczny, ponieważ przeciążenie
CharStreams.toString(Readable)
stwierdza:Oznacza to, że Twoje
InputStreamReader
i przez rozszerzenieInputStream
zwrócone przezsupplier.get()
nie zostaną zamknięte po zakończeniu tego kodu.Jeśli, z drugiej strony, wykorzystasz fakt, że wydaje się, że masz już
InputSupplier<InputStream>
przeciążenie i wykorzystałeś jeCharStreams.toString(InputSupplier<R extends Readable & Closeable>
),toString
metoda zajmie się zarówno utworzeniem, jak i zamknięciemReader
.To jest dokładnie to, co zasugerował Jon Skeet, z wyjątkiem tego, że w rzeczywistości nie ma żadnego przeciążenia,
CharStreams.newReaderSupplier
które pobieraInputStream
jako dane wejściowe ... musisz podać muInputSupplier
:Punkt
InputSupplier
to, aby ułatwić sobie życie, umożliwiając guawie obsługę części, które wymagają brzydkiegotry-finally
bloku, aby zapewnić prawidłowe zamknięcie zasobów.Edycja: Osobiście uważam, że następujące (tak naprawdę to napisałbym, po prostu rozbijały kroki w powyższym kodzie)
być znacznie mniej szczegółowym niż to:
To mniej więcej tyle, ile trzeba by napisać, żeby samemu sobie z tym poradzić.
Edycja: luty 2014
InputSupplier
aOutputSupplier
metody, które ich używają, zostały uznane za przestarzałe w Guava 16.0. Ich zamienniki sąByteSource
,CharSource
,ByteSink
iCharSink
. Biorąc pod uwagęByteSource
, możesz teraz pobrać jego zawartość w następujący sposóbString
:źródło
InputStream
i chcesz uzyskać to jako aString
,CharStreams.toString(new InputStreamReader(inputStream, charset))
to jest droga.ByteSource
iCharSource
są specjalnie przeznaczone do przypadków, w których masz coś, co może działać jako źródłoInputStream
s lubReader
s.Jeśli masz
Readable
, możesz użyćCharStreams.toString(Readable)
. Więc prawdopodobnie możesz wykonać następujące czynności:Zmusza cię do określenia zestawu znaków, co chyba i tak powinieneś zrobić.
źródło
InputSupplier<InputStream>
, zdecydowanie polecam używanieCharStreams.newReaderSupplier(supplier, Charsets.UTF_8)
zamiastnew InputStreamReader
. Powodem jest to, że gdy biorąc pod uwagęInputStreamReader
,toString
będzie nie blisko, żeReader
(a więc nie strumienia bazowego!). UżywającInputSupplier
for theReader
,toString
metoda zajmie się zamknięciemReader
.AKTUALIZACJA : Patrząc wstecz, nie podoba mi się moje stare rozwiązanie. Poza tym jest rok 2013 i są dostępne lepsze alternatywy dla Java7. Oto, czego teraz używam:
lub jeśli z InputSupplier
źródło
Prawie. Możesz użyć czegoś takiego:
Osobiście nie uważam, że
IOUtils.toString(InputStream)
jest to „miłe” - ponieważ zawsze używa domyślnego kodowania platformy, które prawie nigdy nie jest tym, czego chcesz. Istnieje przeciążenie, które przyjmuje nazwę kodowania, ale używanie nazw nie jest dobrym pomysłem IMO. Dlatego lubięCharsets.*
.EDIT: Nie, że powyższe należy przedsięwziąć
InputSupplier<InputStream>
jakstreamSupplier
. Jeśli masz już strumień, możesz to łatwo zaimplementować:źródło
Charsets.UTF_8.name()
- bardziej odporne na typo.Inną opcją jest odczytanie bajtów ze Stream i utworzenie z nich ciągu:
To nie jest „czysta” guawa, ale jest trochę krótsza.
źródło
ByteStreams.toByteArray()
nie zamyka strumienia, zgodnie z Javadoc.Opierając się na zaakceptowanej odpowiedzi, oto metoda narzędziowa, która kpi z zachowania
IOUtils.toString()
(a także przeciążonej wersji z zestawem znaków). Ta wersja powinna być bezpieczna, prawda?źródło
Istnieje znacznie krótsze rozwiązanie autozamykania w przypadku, gdy strumień wejściowy pochodzi z zasobu classpath:
Wykorzystuje zasoby guawy , zainspirowane IOExplained .
źródło
EDYCJA (2015): Okio to najlepsza abstrakcja i narzędzia do I / O w Javie / Androidzie, jakie znam. Używam go cały czas.
Oto czego używam FWIW.
Jeśli mam już strumień w ręku, to:
Jeśli tworzę strumień:
Jako konkretny przykład mogę odczytać zasób pliku tekstowego Androida w następujący sposób:
źródło
Aby uzyskać konkretny przykład, oto jak mogę odczytać zasób pliku tekstowego Androida:
źródło