Mam plik String
, którego chcę użyć jako InputStream
. W Javie 1.0 możesz użyć java.io.StringBufferInputStream
, ale tak było @Deprecrated
(nie bez powodu - nie możesz określić kodowania zestawu znaków):
Ta klasa nie konwertuje poprawnie znaków na bajty. Począwszy od JDK 1.1, preferowanym sposobem tworzenia strumienia z łańcucha jest użycie
StringReader
klasy.
Możesz utworzyć za java.io.Reader
pomocą java.io.StringReader
, ale nie ma adapterów do wzięcia Reader
i utworzenia InputStream
.
Znalazłem starożytny błąd proszący o odpowiednią wymianę, ale nic takiego nie istnieje - o ile wiem.
Często sugerowanym rozwiązaniem jest użycie java.lang.String.getBytes()
jako danych wejściowych do java.io.ByteArrayInputStream
:
public InputStream createInputStream(String s, String charset)
throws java.io.UnsupportedEncodingException {
return new ByteArrayInputStream(s.getBytes(charset));
}
ale to oznacza materializację całości String
w pamięci jako tablicę bajtów i udaremnia cel strumienia. W większości przypadków nie jest to wielka sprawa, ale szukałem czegoś, co zachowałoby intencję strumienia - aby jak najmniej danych było (ponownie) zmaterializowanych w pamięci.
źródło
new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8))
Jeśli nie masz nic przeciwko zależności od pakietu commons-io , możesz użyć metody IOUtils.toInputStream (tekst String) .
źródło
Istnieje adapter firmy Apache Commons-IO, który dostosowuje się z programu Reader do InputStream i nazywa się ReaderInputStream .
Przykładowy kod:
Źródła: https://stackoverflow.com/a/27909221/5658642
źródło
Moim zdaniem najłatwiejszym sposobem na to jest przepchnięcie danych przez moduł Writer:
Implementacja JVM Używam danych wypychanych w porcjach 8K, ale możesz mieć pewien wpływ na rozmiar bufora, zmniejszając liczbę znaków zapisywanych jednocześnie i wywołując flush.
Alternatywa dla pisania własnego opakowania CharsetEncoder w celu użycia Writera do kodowania danych, chociaż jest to trochę trudne. Powinno to być niezawodne (jeśli nieefektywne) wdrożenie:
źródło
Cóż, jednym z możliwych sposobów jest:
PipedOutputStream
PipedInputStream
OutputStreamWriter
wokółPipedOutputStream
(możesz określić kodowanie w konstruktorze)OutputStreamWriter
można przeczytać wPipedInputStream
!Oczywiście wydaje się to raczej hakerskim sposobem na zrobienie tego, ale przynajmniej tak jest.
źródło
Rozwiązaniem jest utworzenie własnego, tworząc
InputStream
implementację, która prawdopodobniejava.nio.charset.CharsetEncoder
użyłaby do zakodowania każdegochar
lub fragmentuchar
s do tablicy bajtów wInputStream
razie potrzeby.źródło
Możesz skorzystać z pomocy biblioteki org.hsqldb.lib.
źródło
Wiem, że to stare pytanie, ale sam miałem dzisiaj ten sam problem, a to było moje rozwiązanie:
źródło