etc./StackOverFlow

Java에서 InputStream을 어떻게 읽거나 문자열로 변환합니까?

청렴결백한 만능 재주꾼 2021. 9. 28. 00:13
반응형

질문자 :Johnny Maelstrom


java.io.InputStream 객체가 있는 경우 해당 객체를 어떻게 처리하고 String 생성해야 합니까?


텍스트 데이터가 포함 InputStream String 으로 변환하려고 한다고 가정해 보겠습니다. 예를 들어 이를 로그 파일에 쓸 수 있습니다.

InputStream String 변환하는 가장 쉬운 방법은 무엇입니까?

 public String convertStreamToString(InputStream is) { // ??? }


답변자 : Slava Vedenin


이를 수행하는 11가지 주요 방법을 찾은 다른 답변을 요약합니다(아래 참조). 그리고 몇 가지 성능 테스트를 작성했습니다(아래 결과 참조).

InputStream을 문자열로 변환하는 방법:

  1. IOUtils.toString 사용(Apache Utils)

     String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
  2. CharStreams (구아바) 사용

     String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8));
  3. Scanner (JDK) 사용

     Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : "";
  4. 스트림 API 사용(자바 8). 경고 : 이 솔루션은 다른 줄 바꿈(예: \r\n )을 \n 합니다.

     String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n"));
  5. 병렬 스트림 API (Java 8) 사용. 경고 : 이 솔루션은 다른 줄 바꿈(예: \r\n )을 \n 합니다.

     String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().parallel().collect(Collectors.joining("\n"));
  6. InputStreamReaderStringBuilder (JDK) 사용

     int bufferSize = 1024; char[] buffer = new char[bufferSize]; StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8); for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) { out.append(buffer, 0, numRead); } return out.toString();
  7. StringWriterIOUtils.copy (Apache Commons)

     StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString();
  8. ByteArrayOutputStreaminputStream.read (JDK) 사용

     ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; for (int length; (length = inputStream.read(buffer)) != -1; ) { result.write(buffer, 0, length); } // StandardCharsets.UTF_8.name() > JDK 7 return result.toString("UTF-8");
  9. BufferedReader (JDK) 사용. 경고: 이 솔루션은 다른 줄 바꿈(예: \n\r )을 line.separator 시스템 속성(예: Windows에서 "\r\n"으로)으로 변환합니다.

     String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(); for (String line; (line = reader.readLine()) != null; ) { if (result.length() > 0) { result.append(newLine); } result.append(line); } return result.toString();
  10. BufferedInputStreamByteArrayOutputStream (JDK) 사용

     BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); for (int result = bis.read(); result != -1; result = bis.read()) { buf.write((byte) result); } // StandardCharsets.UTF_8.name() > JDK 7 return buf.toString("UTF-8");
  11. inputStream.read()StringBuilder (JDK) 사용. 경고 : 이 솔루션은 예를 들어 러시아어 텍스트와 같은 유니코드에 문제가 있습니다(유니코드가 아닌 텍스트에서만 올바르게 작동).

     StringBuilder sb = new StringBuilder(); for (int ch; (ch = inputStream.read()) != -1; ) { sb.append((char) ch); } return sb.toString();

경고 :

  1. 솔루션 4, 5 및 9는 서로 다른 줄 바꿈을 하나로 변환합니다.

  2. 솔루션 11은 유니코드 텍스트에서 제대로 작동하지 않습니다.

성능 테스트

String (길이 = 175), github의 URL(모드 = 평균 시간, 시스템 = Linux, 점수 1,343이 최고임)에 대한 성능 테스트:

 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

String (길이 = 50100), github의 URL(모드 = 평균 시간, 시스템 = Linux, 점수 200,715가 최고임)에 대한 성능 테스트:

 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

그래프(Windows 7 시스템의 입력 스트림 길이에 따른 성능 테스트)
여기에 이미지 설명 입력

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


답변자 : Harry Lime


이를 수행하는 좋은 방법은 Apache commons IOUtils InputStreamStringWriter 에 복사하는 것입니다.

 StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, encoding); String theString = writer.toString();

또는

 // NB: does not close inputStream, you'll have to use try-with-resources for that String theString = IOUtils.toString(inputStream, encoding);

또는 스트림과 작성기를 혼합하지 않으려면 ByteArrayOutputStream 사용할 수 있습니다.



답변자 : Pavel Repin


다음은 표준 Java 라이브러리만 사용하는 방법입니다(스트림이 닫히지 않고 마일리지가 다를 수 있음).

 static String convertStreamToString(java.io.InputStream is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; }

"Stupid Scanner tricks" 기사에서 이 트릭을 배웠습니다. 그것이 작동하는 이유는 Scanner 가 스트림의 토큰을 반복하고 이 경우 "입력 경계의 시작"(\A)을 사용하여 토큰을 분리하므로 스트림의 전체 내용에 대해 하나의 토큰만 제공하기 때문입니다.

입력 스트림의 인코딩에 대해 구체적이어야 하는 경우 사용할 문자 집합(예: "UTF-8")을 나타내는 Scanner

모자 팁은 또한 제이콥 에게 가는데, 그는 그 기사를 언급한 적이 있습니다.



답변자 : Chinnery


Apache Commons는 다음을 허용합니다.

 String myString = IOUtils.toString(myInputStream, "UTF-8");

물론 UTF-8 외에 다른 문자 인코딩을 선택할 수도 있습니다.

참조: ( 문서 )



답변자 : Community Wiki


파일을 고려하면 먼저 java.io.Reader 인스턴스를 가져와야 합니다. 그런 다음 이를 읽고 StringBuilder 추가할 수 있습니다(여러 스레드에서 액세스하지 않는 경우 StringBuffer StringBuilder 가 더 빠름). 여기서 트릭은 블록 단위로 작업하므로 다른 버퍼링 스트림이 필요하지 않다는 것입니다. 블록 크기는 런타임 성능 최적화를 위해 매개변수화됩니다.

 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(); }


답변자 : sampathpremarathna


사용하다:

 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();


답변자 : Sakuraba


Google 컬렉션/구아바를 사용하는 경우 다음을 수행할 수 있습니다.

 InputStream stream = ... String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8)); Closeables.closeQuietly(stream);

InputStreamReader 대한 두 번째 매개변수(예: Charsets.UTF_8)는 필요하지 않지만 일반적으로 알고 있는 경우 인코딩을 지정하는 것이 좋습니다.



답변자 : TacB0sS


이것은 Android 및 기타 JVM에 완벽하게 맞는 최고의 순수 Java 솔루션입니다.

이 솔루션은 놀라울 정도로 잘 작동합니다... 간단하고 빠르며 크고 작은 스트림에서도 똑같이 작동합니다!! (위의 벤치마크 참조. 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; }


답변자 : Tagir Valeev


완전성을 위해 Java 9 솔루션이 있습니다.

 public static String toString(InputStream input) throws IOException { return new String(input.readAllBytes(), StandardCharsets.UTF_8); }

이것은 Java 9에 추가된 readAllBytes 메소드를 사용합니다.



답변자 : Jon Moore


사용하다:

 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(); }


답변자 : Drew Noakes


다음은 몇 가지 실험을 거쳐 생각해낸 가장 우아한 순수 Java(라이브러리 없음) 솔루션입니다.

 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(); }


답변자 : Ilya Gazman


여기에서 14개의 개별 답변에 대한 벤치마크를 수행했습니다(크레딧을 제공하지 못해 죄송하지만 중복 항목이 너무 많습니다).

결과는 매우 놀랍습니다. Apache IOUtils 가 가장 느리고 ByteArrayOutputStream 이 가장 빠른 솔루션인 것으로 나타났습니다.

그래서 먼저 가장 좋은 방법은 다음과 같습니다.

 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); } }

20주기에서 20MB 임의 바이트의 벤치마크 결과

시간(밀리초)

  • ByteArrayOutputStreamTest: 194
  • 니오스트림: 198
  • Java9ISTransferTo: 201
  • Java9ISReadAllBytes: 205
  • BufferedInputStreamVsByteArrayOutputStream: 314
  • ApacheStringWriter2: 574
  • GuavaCharStreams: 589
  • ScannerReaderNoNextTest: 614
  • 스캐너 리더: 633
  • ApacheStringWriter: 1544
  • StreamApi: 오류
  • ParallelStreamApi: 오류
  • BufferReaderTest: 오류
  • InputStreamAndStringBuilder: 오류

벤치마크 소스 코드

 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); } } }


답변자 : Simon Kuang


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. } }

더 간결한 점을 제외하고는 다른 답변과 본질적으로 동일합니다.



답변자 : Brett Holt


항상 시간이 중요하기 때문에 몇 가지 타이밍 테스트를 실행했습니다.

응답을 String 3가지 다른 방법으로 얻으려고 했습니다. (아래에 표시)
가독성을 위해 try/catch 블록을 생략했습니다.

컨텍스트를 제공하기 위해 다음은 세 가지 접근 방식 모두에 대한 이전 코드입니다.

 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();

삼)

 InputStream iStream = method.getResponseBodyAsStream(); StringWriter writer = new StringWriter(); IOUtils.copy(iStream, writer, "UTF-8"); response = writer.toString();

따라서 동일한 요청/응답 데이터로 각 접근 방식에 대해 500번의 테스트를 실행한 후의 수치는 다음과 같습니다. 다시 한 번, 이것들은 내 발견이며 귀하의 발견은 정확히 동일하지 않을 수 있지만 이러한 접근 방식의 효율성 차이를 다른 사람들에게 알리기 위해 이 글을 썼습니다.

순위:
접근법 #1
접근 방식 #3 - #1보다 2.6% 느림
접근 #2 - #1보다 4.3% 느림

이러한 접근 방식은 응답을 가져와서 문자열을 생성하는 데 적합한 솔루션입니다.



답변자 : czerny


Stream 을 사용하는 순수 Java 솔루션은 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())); } }

다른 답변 아래 Christoffer Hammarström이 언급했듯이 Charset 을 명시적으로 지정하는 것이 더 안전합니다. 즉, InputStreamReader 생성자는 다음과 같이 변경할 수 있습니다.

 new InputStreamReader(is, Charset.forName("UTF-8"))


답변자 : TKH


다음은 다소 정리되고 함수로 표시되는 sampath의 답변입니다.

 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(); }


답변자 : Jack


모험심을 느끼고 있다면 Scala와 Java를 혼합하여 다음과 같이 끝낼 수 있습니다.

 scala.io.Source.fromInputStream(is).mkString("")

Java와 Scala 코드 및 라이브러리를 혼합하면 이점이 있습니다.

여기에서 전체 설명을 참조하십시오: 스칼라에서 InputStream을 문자열로 변환하는 관용적 방법



답변자 : DJDaveMark


Commons IO(FileUtils/IOUtils/CopyUtils)를 사용할 수 없는 경우 다음은 BufferedReader를 사용하여 파일을 한 줄씩 읽는 예입니다.

 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); } }

또는 원시 속도를 원하면 Paul de Vrieze가 제안한 변형을 제안합니다(내부적으로 StringBuffer 사용).

 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); } }


답변자 : Thamme Gowda


스트림 리더를 사용하는 경우 마지막에 스트림을 닫아야 합니다.

 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(); }

편집: JDK 7+에서는 try-with-resources 구성을 사용할 수 있습니다.

 /** * 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(); } }


답변자 : jmehrens


Java 9에서 지원되는 java.io.InputStream.transferTo(OutputStream) 및 문자 집합 이름을 사용하는 ByteArrayOutputStream.toString(String)을 사용합니다.

 public static String gobble(InputStream in, String charsetName) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); in.transferTo(bos); return bos.toString(charsetName); }


답변자 : Hai Zhang


이것은 아파치 구현을 원하지만 전체 라이브러리를 원하지 않는 사람들을 위해 org.apache.commons.io.IOUtils 소스 코드 에서 채택한 답변입니다.

 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(); }


답변자 : Daniel De León


이것이 좋은 이유는 다음과 같습니다.

  • Charset을 안전하게 처리합니다.
  • 읽기 버퍼 크기를 제어합니다.
  • 빌더의 길이를 프로비저닝할 수 있으며 정확한 값일 필요는 없습니다.
  • 라이브러리 종속성이 없습니다.
  • Java 7 이상용입니다.

그것을 하는 방법?

 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(); }

JDK 9의 경우

 public static String inputStreamString(InputStream inputStream) throws IOException { try (inputStream) { return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); } }


답변자 : James


모든 Spring 사용자를 위한 또 다른 것:

 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); }

org.springframework.util.StreamUtils 의 유틸리티 메소드는 FileCopyUtils 의 메소드와 유사하지만 완료되면 스트림을 열어 둡니다.



답변자 : laksys


다음은 타사 라이브러리를 사용하지 않고 InputStreamString 으로 변환하는 완전한 방법입니다. 단일 스레드 환경 StringBuilder 를 사용하고 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(); }


답변자 : Matt Shannon


바이트 배열 버퍼를 사용하여 JDK만 사용하여 수행하는 방법은 다음과 같습니다. 이것이 실제로 commons-io IOUtils.copy() 메서드가 모두 작동하는 방식입니다. InputStream 대신 Reader 에서 복사하는 경우 byte[]char[] []로 바꿀 수 있습니다.

 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);


답변자 : Alex


Kotlin 사용자는 다음을 수행하기만 하면 됩니다.

 println(InputStreamReader(is).readText())

반면

 readText()

Kotlin 표준 라이브러리의 내장 확장 방법입니다.



답변자 : czerny


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(); } }
  • 순수 Java 표준 라이브러리 솔루션 - 라이브러리 없음
  • 자바 10부터 - Reader#transferTo(java.io.Writer)
  • 루프리스 솔루션
  • 개행 문자 처리 없음


답변자 : Raghu K Nair


JDK에서 가장 쉬운 방법은 다음 코드 조각을 사용하는 것입니다.

 String convertToString(InputStream in){ String resource = new Scanner(in).useDelimiter("\\Z").next(); return resource; }


답변자 : Christian Rädel


다음 은 새로운 Stream API InputStream 에서 모든 라인을 수집 하는 Java 8 기반 솔루션입니다.

 public static String toString(InputStream inputStream) { BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); return reader.lines().collect(Collectors.joining( System.getProperty("line.separator"))); }


답변자 : libnull-dev


reduceconcat 측면에서 Java 8에서는 다음과 같이 표현할 수 있습니다.

 String fromFile = new BufferedReader(new InputStreamReader(inputStream)).lines().reduce(String::concat).get();


출처 : Here


출처 : http:www.stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java">

반응형