Jak odczytać / przekonwertować strumień wejściowy na ciąg znaków w Javie?
Jeśli posiadasz java.io.InputStream
obiekt, jak należy go przetworzyć i wyprodukować String
?
Załóżmy, że mam InputStream
, który zawiera dane tekstowe i chcę je przekonwertować na String
, więc na przykład mogę zapisać je do pliku dziennika.
Jaki jest najprostszy sposób, aby wziąć InputStream
i przekonwertować go na String
?
public String convertStreamToString(InputStream is) {
// ???
}
30 answers
Dobrym sposobem na to jest użycie Apache commons IOUtils
aby skopiować {[3] } do StringWriter
... coś jak
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();
Lub nawet
// NB: does not close inputStream, you'll have to use try-with-resources for that
String theString = IOUtils.toString(inputStream, encoding);
Alternatywnie możesz użyć ByteArrayOutputStream
, jeśli nie chcesz mieszać swoich strumieni i pisarzy
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-21 13:09:50
Podsumuj inne odpowiedzi znalazłem 11 głównych sposobów, aby to zrobić (patrz poniżej). I napisałem kilka testów wydajności (patrz wyniki poniżej):
Sposób konwersji strumienia wejściowego na ciąg znaków:
-
Using
IOUtils.toString
(Apache Utils)String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
-
Using
CharStreams
(Guava)String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8));
-
Using
Scanner
(JDK)Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : "";
-
Używając Stream API (Java 8). Ostrzeżenie : To rozwiązanie konwertuje inną linię przerwy (jak
\r\n
) na\n
.String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n"));
-
Używając parallel Stream API (Java 8). Ostrzeżenie : To rozwiązanie konwertuje różne podziały linii (np.
\r\n
) na\n
.String result = new BufferedReader(new InputStreamReader(inputStream)).lines() .parallel().collect(Collectors.joining("\n"));
-
Using
InputStreamReader
andStringBuilder
(JDK)final int bufferSize = 1024; final char[] buffer = new char[bufferSize]; final StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8); int charsRead; while((charsRead = in.read(buffer, 0, buffer.length)) > 0) { out.append(buffer, 0, charsRead); } return out.toString();
-
Using
StringWriter
andIOUtils.copy
(Apache Commons)StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString();
-
Using
ByteArrayOutputStream
andinputStream.read
(JDK)ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length); } // StandardCharsets.UTF_8.name() > JDK 7 return result.toString("UTF-8");
-
Używając
BufferedReader
(JDK). Ostrzeżenie: To rozwiązanie konwertuje różne podziały wierszy (jak\n\r
) na właściwość systemowąline.separator
(na przykład w Windows na "\R\n").String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(); boolean flag = false; for (String line; (line = reader.readLine()) != null; ) { result.append(flag? newLine: "").append(line); flag = true; } return result.toString();
-
Using
BufferedInputStream
andByteArrayOutputStream
(JDK)BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while(result != -1) { buf.write((byte) result); result = bis.read(); } // StandardCharsets.UTF_8.name() > JDK 7 return buf.toString("UTF-8");
-
Używając
inputStream.read()
iStringBuilder
(JDK). Ostrzeżenie : To rozwiązanie ma problemy z Unicode, na przykład z tekstem rosyjskim (działa poprawnie tylko z tekstem innym niż Unicode)int ch; StringBuilder sb = new StringBuilder(); while((ch = inputStream.read()) != -1) sb.append((char)ch); reset(); return sb.toString();
Ostrzeżenie :
Rozwiązania 4, 5 i 9 konwertują różne linie Przerwa na 1.
-
Rozwiązanie 11 nie może działać poprawnie z tekstem Unicode
Testy wydajnościowe
Testy wydajności dla małych String
(długość = 175), url w github (mode = średni czas, system = Linux, wynik 1,343 jest najlepszy):
Benchmark Mode Cnt Score Error Units
8. ByteArrayOutputStream and read (JDK) avgt 10 1,343 ± 0,028 us/op
6. InputStreamReader and StringBuilder (JDK) avgt 10 6,980 ± 0,404 us/op
10. BufferedInputStream, ByteArrayOutputStream avgt 10 7,437 ± 0,735 us/op
11. InputStream.read() and StringBuilder (JDK) avgt 10 8,977 ± 0,328 us/op
7. StringWriter and IOUtils.copy (Apache) avgt 10 10,613 ± 0,599 us/op
1. IOUtils.toString (Apache Utils) avgt 10 10,605 ± 0,527 us/op
3. Scanner (JDK) avgt 10 12,083 ± 0,293 us/op
2. CharStreams (guava) avgt 10 12,999 ± 0,514 us/op
4. Stream Api (Java 8) avgt 10 15,811 ± 0,605 us/op
9. BufferedReader (JDK) avgt 10 16,038 ± 0,711 us/op
5. parallel Stream Api (Java 8) avgt 10 21,544 ± 0,583 us/op
Testy wydajności dla dużych String
(Długość = 50100), url w github (mode = średni czas, system = Linux, wynik 200,715 jest najlepszy):
Benchmark Mode Cnt Score Error Units
8. ByteArrayOutputStream and read (JDK) avgt 10 200,715 ± 18,103 us/op
1. IOUtils.toString (Apache Utils) avgt 10 300,019 ± 8,751 us/op
6. InputStreamReader and StringBuilder (JDK) avgt 10 347,616 ± 130,348 us/op
7. StringWriter and IOUtils.copy (Apache) avgt 10 352,791 ± 105,337 us/op
2. CharStreams (guava) avgt 10 420,137 ± 59,877 us/op
9. BufferedReader (JDK) avgt 10 632,028 ± 17,002 us/op
5. parallel Stream Api (Java 8) avgt 10 662,999 ± 46,199 us/op
4. Stream Api (Java 8) avgt 10 701,269 ± 82,296 us/op
10. BufferedInputStream, ByteArrayOutputStream avgt 10 740,837 ± 5,613 us/op
3. Scanner (JDK) avgt 10 751,417 ± 62,026 us/op
11. InputStream.read() and StringBuilder (JDK) avgt 10 2919,350 ± 1101,942 us/op
Wykresy (testy wydajności w zależności od długości strumienia wejściowego w systemie Windows 7)
length 182 546 1092 3276 9828 29484 58968
test8 0.38 0.938 1.868 4.448 13.412 36.459 72.708
test4 2.362 3.609 5.573 12.769 40.74 81.415 159.864
test5 3.881 5.075 6.904 14.123 50.258 129.937 166.162
test9 2.237 3.493 5.422 11.977 45.98 89.336 177.39
test6 1.261 2.12 4.38 10.698 31.821 86.106 186.636
test7 1.601 2.391 3.646 8.367 38.196 110.221 211.016
test1 1.529 2.381 3.527 8.411 40.551 105.16 212.573
test3 3.035 3.934 8.606 20.858 61.571 118.744 235.428
test2 3.136 6.238 10.508 33.48 43.532 118.044 239.481
test10 1.593 4.736 7.527 20.557 59.856 162.907 323.147
test11 3.913 11.506 23.26 68.644 207.591 600.444 1211.545
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-09 15:10:29
Oto sposób na użycie tylko standardowej biblioteki Java(pamiętaj, że strumień nie jest zamknięty, twój przebieg może się różnić).
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
Nauczyłem się tej sztuczki z artykułu"głupie sztuczki skanera". To działa, ponieważ Scanner iteruje nad tokenami w strumieniu i w tym przypadku oddzielamy tokeny za pomocą "początku granicy wejściowej" (\a), dając nam w ten sposób tylko jeden token dla całej zawartości strumienia.
Uwaga, Jeśli chcesz być konkretny na temat kodowanie strumienia wejściowego, możesz podać drugi argument konstruktora Scanner
, który wskazuje, jakiego zestawu znaków użyć (np."UTF-8").
Końcówka kapelusza idzie również do Jacoba , który kiedyś wskazał mi wspomniany artykuł.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 10:33:54
Apache Commons pozwala:
String myString = IOUtils.toString(myInputStream, "UTF-8");
Oczywiście można było wybrać inne kodowanie znaków poza UTF-8.
Zobacz też: ( dokumentacja )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 10:29:32
Biorąc pod uwagę plik należy najpierw uzyskać instancję java.io.Reader
. To może być odczytane i dodane do StringBuilder
(nie potrzebujemy StringBuffer
, Jeśli nie uzyskujemy do niego dostępu w wielu wątkach i StringBuilder
jest szybsze). Sztuczka polega na tym, że pracujemy w blokach i jako takie nie potrzebujemy innych strumieni buforujących. Rozmiar bloku jest parametryzowany w celu optymalizacji wydajności w czasie pracy.
public static String slurp(final InputStream is, final int bufferSize) {
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
try (Reader in = new InputStreamReader(is, "UTF-8")) {
for (;;) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0)
break;
out.append(buffer, 0, rsz);
}
}
catch (UnsupportedEncodingException ex) {
/* ... */
}
catch (IOException ex) {
/* ... */
}
return out.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 10:23:45
Użycie:
InputStream in = /* Your InputStream */;
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;
while ((read=br.readLine()) != null) {
//System.out.println(read);
sb.append(read);
}
br.close();
return sb.toString();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 10:35:00
Jeśli korzystasz z Google-Collections/Guava, możesz wykonać następujące czynności:
InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);
Zauważ, że drugi parametr (tj. znaki.UTF_8) dla InputStreamReader
nie jest konieczne, ale ogólnie dobrym pomysłem jest podanie kodowania, jeśli je znasz (co powinieneś!)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-30 16:35:54
Jest to najlepsze rozwiązanie pure Java, które idealnie pasuje do Androida i każdego innego JVM.
To rozwiązanie działa zadziwiająco dobrze... jest prosty, szybki i działa na małych i dużych strumieniach tak samo!! (patrz punkt odniesienia powyżej.. nie. 8)public String readFullyAsString(InputStream inputStream, String encoding)
throws IOException {
return readFully(inputStream).toString(encoding);
}
public byte[] readFullyAsBytes(InputStream inputStream)
throws IOException {
return readFully(inputStream).toByteArray();
}
private ByteArrayOutputStream readFully(InputStream inputStream)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-23 20:38:45
Dla kompletności tutaj jest Java 9 rozwiązanie:
public static String toString(InputStream input) throws IOException {
return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}
To wykorzystuje readAllBytes
metoda dodana do Javy 9.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-18 22:50:35
Użycie:
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
public static String readInputStreamAsString(InputStream in)
throws IOException {
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
byte b = (byte)result;
buf.write(b);
result = bis.read();
}
return buf.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 10:30:05
Oto najbardziej eleganckie, czyste rozwiązanie Java (bez biblioteki), które wymyśliłem po kilku eksperymentach:
public static String fromStream(InputStream in) throws IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
return out.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-07 16:39:30
Zrobiłem benchmark na 14 różnych odpowiedzi tutaj (przepraszam, że nie udzielam kredytów, ale jest zbyt wiele duplikatów).
Wynik jest bardzo zaskakujący. Okazuje się, że Apache IOUtils jest najwolniejszym iByteArrayOutputStream
jest najszybszym rozwiązaniem:
Więc najpierw jest najlepsza metoda:
public String inputStreamToString(InputStream inputStream) throws IOException {
try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(UTF_8);
}
}
Wyniki porównawcze, 20 MB losowych bajtów w 20 cyklach
Czas w milisekundach
- ByteArrayOutputStreamTest: 194
- NioStream: 198
- Java9: 201
- Java9ISReadAllBytes: 205
- BufferedInputStreamVsByteArrayOutputstream: 314
- ApacheStringWriter2: 574
- GuavaCharStreams: 589
- ScannerReaderNoNextTest: 614
- ScannerReader: 633
- apachestringwriter: 1544
- StreamApi: Error
- ParallelStreamApi: Error
- BufferReaderTest: Błąd
- InputStreamAndStringBuilder: Error
Benchmark kod źródłowy
import com.google.common.io.CharStreams;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
* Created by Ilya Gazman on 2/13/18.
*/
public class InputStreamToString {
private static final String UTF_8 = "UTF-8";
public static void main(String... args) {
log("App started");
byte[] bytes = new byte[1024 * 1024];
new Random().nextBytes(bytes);
log("Stream is ready\n");
try {
test(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void test(byte[] bytes) throws IOException {
List<Stringify> tests = Arrays.asList(
new ApacheStringWriter(),
new ApacheStringWriter2(),
new NioStream(),
new ScannerReader(),
new ScannerReaderNoNextTest(),
new GuavaCharStreams(),
new StreamApi(),
new ParallelStreamApi(),
new ByteArrayOutputStreamTest(),
new BufferReaderTest(),
new BufferedInputStreamVsByteArrayOutputStream(),
new InputStreamAndStringBuilder(),
new Java9ISTransferTo(),
new Java9ISReadAllBytes()
);
String solution = new String(bytes, "UTF-8");
for (Stringify test : tests) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
String s = test.inputStreamToString(inputStream);
if (!s.equals(solution)) {
log(test.name() + ": Error");
continue;
}
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < 20; i++) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
test.inputStreamToString(inputStream);
}
}
log(test.name() + ": " + (System.currentTimeMillis() - startTime));
}
}
private static void log(String message) {
System.out.println(message);
}
interface Stringify {
String inputStreamToString(InputStream inputStream) throws IOException;
default String name() {
return this.getClass().getSimpleName();
}
}
static class ApacheStringWriter implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, UTF_8);
return writer.toString();
}
}
static class ApacheStringWriter2 implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
return IOUtils.toString(inputStream, UTF_8);
}
}
static class NioStream implements Stringify {
@Override
public String inputStreamToString(InputStream in) throws IOException {
ReadableByteChannel channel = Channels.newChannel(in);
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 16);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
WritableByteChannel outChannel = Channels.newChannel(bout);
while (channel.read(byteBuffer) > 0 || byteBuffer.position() > 0) {
byteBuffer.flip(); //make buffer ready for write
outChannel.write(byteBuffer);
byteBuffer.compact(); //make buffer ready for reading
}
channel.close();
outChannel.close();
return bout.toString(UTF_8);
}
}
static class ScannerReader implements Stringify {
@Override
public String inputStreamToString(InputStream is) throws IOException {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
static class ScannerReaderNoNextTest implements Stringify {
@Override
public String inputStreamToString(InputStream is) throws IOException {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.next();
}
}
static class GuavaCharStreams implements Stringify {
@Override
public String inputStreamToString(InputStream is) throws IOException {
return CharStreams.toString(new InputStreamReader(
is, UTF_8));
}
}
static class StreamApi implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
return new BufferedReader(new InputStreamReader(inputStream))
.lines().collect(Collectors.joining("\n"));
}
}
static class ParallelStreamApi implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
return new BufferedReader(new InputStreamReader(inputStream)).lines()
.parallel().collect(Collectors.joining("\n"));
}
}
static class ByteArrayOutputStreamTest implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(UTF_8);
}
}
}
static class BufferReaderTest implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
String newLine = System.getProperty("line.separator");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder result = new StringBuilder(UTF_8);
String line;
boolean flag = false;
while ((line = reader.readLine()) != null) {
result.append(flag ? newLine : "").append(line);
flag = true;
}
return result.toString();
}
}
static class BufferedInputStreamVsByteArrayOutputStream implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while (result != -1) {
buf.write((byte) result);
result = bis.read();
}
return buf.toString(UTF_8);
}
}
static class InputStreamAndStringBuilder implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
int ch;
StringBuilder sb = new StringBuilder(UTF_8);
while ((ch = inputStream.read()) != -1)
sb.append((char) ch);
return sb.toString();
}
}
static class Java9ISTransferTo implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
inputStream.transferTo(bos);
return bos.toString(UTF_8);
}
}
static class Java9ISReadAllBytes implements Stringify {
@Override
public String inputStreamToString(InputStream inputStream) throws IOException {
return new String(inputStream.readAllBytes(), UTF_8);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-06 00:45:59
Użyłbym kilku sztuczek Java 8.
public static String streamToString(final InputStream inputStream) throws Exception {
// buffering optional
try
(
final BufferedReader br
= new BufferedReader(new InputStreamReader(inputStream))
) {
// parallel optional
return br.lines().parallel().collect(Collectors.joining("\n"));
} catch (final IOException e) {
throw new RuntimeException(e);
// whatever.
}
}
Zasadniczo tak samo jak niektóre inne odpowiedzi, z wyjątkiem bardziej zwięzłych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 11:03:54
Przeprowadziłam testy czasowe, bo czas zawsze ma znaczenie.
Próbowałem uzyskać odpowiedź w ciągu 3 różne sposoby. (pokazane poniżej)
Pominąłem bloki try / catch dla czytelności.
Aby podać kontekst, jest to poprzedzający kod dla wszystkich 3 podejść:
String response;
String url = "www.blah.com/path?key=value";
GetMethod method = new GetMethod(url);
int status = client.executeMethod(method);
1)
response = method.getResponseBodyAsString();
2)
InputStream resp = method.getResponseBodyAsStream();
InputStreamReader is=new InputStreamReader(resp);
BufferedReader br=new BufferedReader(is);
String read = null;
StringBuffer sb = new StringBuffer();
while((read = br.readLine()) != null) {
sb.append(read);
}
response = sb.toString();
3)
InputStream iStream = method.getResponseBodyAsStream();
StringWriter writer = new StringWriter();
IOUtils.copy(iStream, writer, "UTF-8");
response = writer.toString();
Tak więc, po przeprowadzeniu 500 testów na każdym podejściu z tymi samymi danymi żądania / odpowiedzi, oto liczby. Po raz kolejny, są to moje ustalenia i twoje ustalenia mogą nie być dokładnie takie same, ale napisałem to, aby dać wskazówki innym o różnicach wydajności tych podejść.
Ranga:
Podejście #1
Podejście #3-2.6% wolniejsze niż #1
Podejście # 2-4,3% wolniejsze niż #1
Każde z tych podejść jest odpowiednim rozwiązaniem do przechwytywania odpowiedzi i tworzenia z niej ciągu znaków.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-17 08:55:23
Pure Java solution using Stream s, works since Java 8.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
// ...
public static String inputStreamToString(InputStream is) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
return br.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
Jak wspomniał Christoffer Hammarström poniżej inna odpowiedź bezpieczniej jest jednoznacznie określić kod . Konstruktor InputStreamReader może być zmieniany w następujący sposób:
new InputStreamReader(is, Charset.forName("UTF-8"))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53
Oto mniej więcej odpowiedź sampath ' a, trochę uporządkowana i przedstawiona jako funkcja:
String streamToString(InputStream in) throws IOException {
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
for(String line = br.readLine(); line != null; line = br.readLine())
out.append(line);
br.close();
return out.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 18:31:12
Gdybyś miał ochotę na przygodę, mógłbyś wymieszać Scalę i Javę i skończyć z tym:
scala.io.Source.fromInputStream(is).mkString("")
Mieszanie kodu Javy i Scali oraz bibliotek ma swoje zalety.
Zobacz pełny opis tutaj: Idiomatyczny sposób konwersji strumienia wejściowego na ciąg znaków w Scali
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:29
Jeśli nie możesz użyć Commons IO (FileUtils/Ioutils/CopyUtils), oto przykład użycia Bufferedreadera do odczytu pliku linia po linii:
public class StringFromFile {
public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
InputStream is = StringFromFile.class.getResourceAsStream("file.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is/*, "UTF-8"*/));
final int CHARS_PER_PAGE = 5000; //counting spaces
StringBuilder builder = new StringBuilder(CHARS_PER_PAGE);
try {
for(String line=br.readLine(); line!=null; line=br.readLine()) {
builder.append(line);
builder.append('\n');
}
}
catch (IOException ignore) { }
String text = builder.toString();
System.out.println(text);
}
}
Lub jeśli chcesz surowej prędkości, proponuję wariację na temat tego, co zasugerował Paul de Vrieze (który unika używania Stringwritera (który używa Stringbuffera wewnętrznie):
public class StringFromFileFast {
public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
InputStream is = StringFromFileFast.class.getResourceAsStream("file.txt");
InputStreamReader input = new InputStreamReader(is/*, "UTF-8"*/);
final int CHARS_PER_PAGE = 5000; //counting spaces
final char[] buffer = new char[CHARS_PER_PAGE];
StringBuilder output = new StringBuilder(CHARS_PER_PAGE);
try {
for(int read = input.read(buffer, 0, buffer.length);
read != -1;
read = input.read(buffer, 0, buffer.length)) {
output.append(buffer, 0, read);
}
} catch (IOException ignore) { }
String text = output.toString();
System.out.println(text);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 10:31:01
Upewnij się, że strumienie są zamykane na końcu, jeśli używasz czytników strumieniowych
private String readStream(InputStream iStream) throws IOException {
//build a Stream Reader, it can read char by char
InputStreamReader iStreamReader = new InputStreamReader(iStream);
//build a buffered Reader, so that i can read whole line at once
BufferedReader bReader = new BufferedReader(iStreamReader);
String line = null;
StringBuilder builder = new StringBuilder();
while((line = bReader.readLine()) != null) { //Read till end
builder.append(line);
builder.append("\n"); // append new line to preserve lines
}
bReader.close(); //close all opened stuff
iStreamReader.close();
//iStream.close(); //EDIT: Let the creator of the stream close it!
// some readers may auto close the inner stream
return builder.toString();
}
EDIT: na JDK 7+ możesz użyć try-with-resources construct.
/**
* Reads the stream into a string
* @param iStream the input stream
* @return the string read from the stream
* @throws IOException when an IO error occurs
*/
private String readStream(InputStream iStream) throws IOException {
//Buffered reader allows us to read line by line
try (BufferedReader bReader =
new BufferedReader(new InputStreamReader(iStream))){
StringBuilder builder = new StringBuilder();
String line;
while((line = bReader.readLine()) != null) { //Read till end
builder.append(line);
builder.append("\n"); // append new line to preserve lines
}
return builder.toString();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 19:28:51
Jest to odpowiedź zaadaptowana z org.apache.commons.io.IOUtils
kod źródłowy , dla tych, którzy chcą mieć implementację apache, ale nie chcą całej biblioteki.
private static final int BUFFER_SIZE = 4 * 1024;
public static String inputStreamToString(InputStream inputStream, String charsetName)
throws IOException {
StringBuilder builder = new StringBuilder();
InputStreamReader reader = new InputStreamReader(inputStream, charsetName);
char[] buffer = new char[BUFFER_SIZE];
int length;
while ((length = reader.read(buffer)) != -1) {
builder.append(buffer, 0, length);
}
return builder.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-10 04:37:28
Ten jest fajny bo:
- bezpiecznie obsługuje zestaw znaków.
- kontrolujesz rozmiar bufora odczytu.
- możesz podać długość konstruktora i nie musi to być dokładna wartość.
- jest wolny od zależności bibliotek.
- jest dla Javy 7 lub wyższej.
Jak to zrobić?
public static String convertStreamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder(2048); // Define a size if you have an idea of it.
char[] read = new char[128]; // Your buffer size.
try (InputStreamReader ir = new InputStreamReader(is, StandardCharsets.UTF_8)) {
for (int i; -1 != (i = ir.read(read)); sb.append(read, 0, i));
}
return sb.toString();
}
Dla JDK 9
public static String inputStreamString(InputStream inputStream) throws IOException {
try (inputStream) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-20 05:57:28
Użyj java.io.InputStream.transferTo(OutputStream) obsługiwanego w Javie 9 i ByteArrayOutputStream.toString (String), który przyjmuje nazwę zestawu znaków:
public static String gobble(InputStream in, String charsetName) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo(bos);
return bos.toString(charsetName);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-28 14:47:28
Kolejny, dla wszystkich wiosennych użytkowników:
import java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;
public String convertStreamToString(InputStream is) throws IOException {
return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}
Metody użytkowe w {[1] } są podobne do tych w FileCopyUtils
, ale pozostawiają strumień otwarty po zakończeniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 10:24:14
Oto pełna metoda konwersji InputStream
na String
bez użycia jakiejkolwiek biblioteki stron trzecich. Użyj StringBuilder
dla środowiska z pojedynczym gwintem, w przeciwnym razie użyj StringBuffer
.
public static String getString( InputStream is) throws IOException {
int ch;
StringBuilder sb = new StringBuilder();
while((ch = is.read()) != -1)
sb.append((char)ch);
return sb.toString();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-16 09:20:36
Oto Jak to zrobić używając tylko JDK używając buforów tablicy bajtów. Tak działają wszystkie metody commons-io IOUtils.copy()
. Możesz zastąpić byte[]
przez char[]
, jeśli kopiujesz z Reader
zamiast InputStream
.
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
...
InputStream is = ....
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
byte[] buffer = new byte[8192];
int count = 0;
try {
while ((count = is.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
}
finally {
try {
is.close();
}
catch (Exception ignore) {
}
}
String charset = "UTF-8";
String inputStreamAsString = baos.toString(charset);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-13 04:30:09
Użytkownicy Kotlina po prostu robią:
println(InputStreamReader(is).readText())
readText()
Jest wbudowaną metodą rozszerzenia Biblioteki Kotlin.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 01:12:24
String inputStreamToString(InputStream inputStream, Charset charset) throws IOException {
try (
final StringWriter writer = new StringWriter();
final InputStreamReader reader = new InputStreamReader(inputStream, charset)
) {
reader.transferTo(writer);
return writer.toString();
}
}
- pure Java standard library solution-no libs
- od Java 10 - Reader#transferTo(java.io.Writer)
- rozwiązanie bez pętli
- Brak obsługi znaków nowej linii
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-05 00:03:47
Najprostszym sposobem w JDK jest użycie poniższych fragmentów kodu.
String convertToString(InputStream in){
String resource = new Scanner(in).useDelimiter("\\Z").next();
return resource;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 20:18:26
Oto moje rozwiązanie oparte na Javie 8 , które wykorzystuje new Stream API do zbierania wszystkich linii z InputStream
:
public static String toString(InputStream inputStream) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
return reader.lines().collect(Collectors.joining(
System.getProperty("line.separator")));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 11:19:27
W kategoriach reduce
i concat
może być wyrażona w Javie 8 jako:
String fromFile = new BufferedReader(new
InputStreamReader(inputStream)).lines().reduce(String::concat).get();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 07:37:29