InputStream을 Java의 String으로 읽거나 변환하는 방법
만약 당신이 a를java.io.InputStream
그해서 그 , 그 물체를 어떻게 생산해야 하는가?String
?
만약 내가 a를 가지고 있다고 가정해 보자.InputStream
텍스트 데이터를 포함하고 있으며 이 데이터를String
예를 들어, 나는 그것을 로그 파일에 쓸 수 있다.
가장 쉽게 취할 수 있는 방법은 무엇인가?InputStream
그리고 그것을 a로 변환하다.String
?
public String convertStreamToString(InputStream is) {
// ???
}
이 작업을 수행하는 11가지 주요 방법을 찾은 다른 답변을 요약하십시오(아래 참조).그리고 몇 가지 성능 테스트를 작성했다(아래 결과 참조):
InputStream을 문자열로 변환하는 방법:
사용.
IOUtils.toString
(Apache Utils)String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
사용.
CharStreams
과바)String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8));
사용.
Scanner
(JDK)Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : "";
Stream API 사용(Java 8).경고:이 솔루션은 서로 다른 줄 바꿈을 변환한다(예:
\r\n
~에게\n
.String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n"));
병렬 스트림 API 사용(Java 8).경고:이 솔루션은 서로 다른 줄 바꿈을 변환한다(예:
\r\n
~에게\n
.String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().parallel().collect(Collectors.joining("\n"));
사용.
InputStreamReader
그리고StringBuilder
(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();
사용.
StringWriter
그리고IOUtils.copy
(Apache Commons)StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString();
사용.
ByteArrayOutputStream
그리고inputStream.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");
사용.
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();
사용.
BufferedInputStream
그리고ByteArrayOutputStream
(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");
사용.
inputStream.read()
그리고StringBuilder
(JDK). 경고:이 솔루션은 예를 들어 러시아어 텍스트와 같은 유니코드에 문제가 있음(유니코드가 아닌 텍스트에서만 올바르게 작동함)StringBuilder sb = new StringBuilder(); for (int ch; (ch = inputStream.read()) != -1; ) { sb.append((char) ch); } return sb.toString();
경고:
솔루션 4, 5, 9는 서로 다른 줄 바꿈을 하나로 변환한다.
솔루션 11이 유니코드 텍스트에서 올바르게 작동하지 않음
성능 테스트
소형의 성능 테스트String
(길이 = 175) url in github(모드 = Average Time, 시스템 = 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), url in github(모드 = 평균 시간, 시스템 = 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(윈도우 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
이를 위한 좋은 방법은 Apache commons를 사용하는 것이다. IOUtils
복사하다InputStream
.StringWriter
것…같은 것
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
스트림과 작가를 혼용하지 않으려면
여기 표준 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" 기사를 통해 배웠다.스캐너가 스트림에서 토큰을 반복하는 이유는 스캐너가 스트림에서 토큰을 반복하기 때문인데, 이 경우 우리는 "입력경계의 시작"(\A)을 사용하여 토큰을 분리해 스트림 전체 내용에 대해 토큰을 하나만 주기 때문이다.
입력 스트림의 인코딩에 대해 구체적으로 설명해야 하는 경우 다음 두 번째 인수를 제공하십시오.Scanner
사용할 문자 집합(예: "UTF-8")을 나타내는 생성자.
모자 팁은 언젠가 그 기사를 내게 가리킨 제이콥에게도 간다.
Apache Commons는 다음을 허용한다.
String myString = IOUtils.toString(myInputStream, "UTF-8");
물론 UTF-8 외에 다른 캐릭터 인코딩을 선택할 수도 있다.
참고 항목: (문서)
파일을 고려하는 것은 먼저 a를 얻어야 한다.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();
}
사용:
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();
Google-Collections/Guava를 사용하는 경우 다음 작업을 수행하십시오.
InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);
두 번째 파라미터(즉, Charsets)에 유의하십시오.UTF_8)의 경우에 InputStreamReader
꼭 필요한 것은 아니지만 일반적으로 인코딩을 알고 있다면 지정하는 것이 좋다(어느 것이 좋을까!).
완벽함을 위해 Java 9 솔루션:
public static String toString(InputStream input) throws IOException {
return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}
이것은 Java 9에 추가된 방법을 사용한다.
이것은 안드로이드와 다른 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;
}
사용:
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();
}
여기 내가 몇 가지 실험 후에 고안한 가장 우아하고 순수한 자바(도서관이 없는) 해결책이 있다.
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();
}
나는 여기서 14개의 뚜렷한 답을 벤치마킹했다. (크레딧을 제공하지 못해서 미안한데 중복이 너무 많다.)
결과는 매우 놀랍다.아파치 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
- Java9ISTranspferTo: 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);
}
}
}
난 자바 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.
}
}
본질적으로 좀 더 간명하다는 점을 제외하고는 다른 답변들과 동일하다.
나는 항상 시간이 중요하기 때문에 타이밍 테스트를 좀 했다.
나는 스트링 3의 다른 방법으로 반응을 이끌어내려고 시도했다.(아래 참조)
읽기 쉽도록 시도/캐치 블록을 빠뜨렸다.
컨텍스트를 제공하려면 다음 3가지 접근방법에 대해 모두 선행 코드를 사용하십시오.
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();
따라서, 동일한 요청/응답 데이터로 각 접근방법에 대해 500개의 테스트를 수행한 후, 여기 숫자가 있다.다시 한 번 말하지만, 이것은 나의 발견이고 당신의 발견은 정확히 같지 않을 수도 있다. 그러나 나는 이러한 접근방식의 효율성 차이를 다른 사람들에게 알리기 위해 이 글을 썼다.
순위:
#1접근 #1
접근 #3 - #1보다 2.6% 느림
접근 #2 - #1보다 4.3% 느림
이러한 접근 방식 중 어느 것이든 응답을 포착하고 응답을 스트링으로 만드는 데 적합한 솔루션이다.
스트림을 사용한 순수한 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 Hammarstöm이 아래 다른 답변에서 언급한 바와 같이 Charset을 명시적으로 지정하는 것이 안전하다.즉, InputStreamReader 생성자는 다음과 같이 변경할 수 있다.
new InputStreamReader(is, Charset.forName("UTF-8"))
좀 더 혹은 덜한 샘패스의 대답은 다음과 같다.
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();
}
모험심을 느낀다면 스칼라와 자바를 섞어서 이렇게 끝낼 수 있을 것이다.
scala.io.Source.fromInputStream(is).mkString("")
자바와 스칼라 코드와 라이브러리를 섞으면 장점이 있다.
자세한 설명은 여기를 참조하십시오.InputStream을 Scala에서 문자열로 변환하는 관용적인 방법
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가 제안한 내용에 대한 변형을 제안한다(StringWriter(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);
}
}
java.io을 사용하십시오.Java 9 및 Charset 이름을 사용하는 ByteArrayOutputStream.toString(String)에서 지원되는 InputStream.toString:
public static String gobble(InputStream in, String charsetName) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo(bos);
return bos.toString(charsetName);
}
스트림 판독기를 사용하는 경우 스트림을 끝내십시오.
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-resource 구성을 사용할 수 있다.
/**
* 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();
}
}
이것은 에서 각색한 대답이다.org.apache.commons.io.IOUtils
소스 코드: apache 구현을 원하지만 전체 라이브러리를 원하지 않는 사용자.
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();
}
이것은 다음과 같은 이유 때문에 좋다.
- 차르셋을 안전하게 처리한다.
- 읽기 버퍼 크기를 제어하는 경우.
- 건설업자의 길이를 프로비저닝할 수 있으며 정확한 값이 될 필요는 없다.
- 라이브러리 종속성이 없음.
- 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);
}
}
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 표준 라이브러리 솔루션 - libs 없음
- Java 10 이후 - Reader#transferTo(java.io.작성자)
- 고리 없는 용액
- 새로운 줄 문자 처리 없음
다른 하나는 모든 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
그러나 그들은 끝나면 개울을 열어둔다.
Kotlin 사용자들은 단순히 다음과 같은 일을 한다.
println(InputStreamReader(is).readText())
반면에
readText()
코틀린 표준 도서관의 내장 확장 방식이다.
변환을 위한 완전한 방법은 다음과 같다.InputStream
String
타사 라이브러리를 사용하지 않고사용하다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();
}
바이트 배열 버퍼를 사용하여 JDK만 사용하는 방법은 다음과 같다. 커먼---오-오(Commons-o)은 되어 있다.IOUtils.copy()
모든 방법이 통한다.교체할 수 있음byte[]
와 함께char[]
A에서 복사하는 경우Reader
…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);
JDK에서 가장 쉬운 방법은 다음과 같은 코드 조각들을 사용하는 것이다.
String convertToString(InputStream in){
String resource = new Scanner(in).useDelimiter("\\Z").next();
return resource;
}
측면에서.reduce
그리고concat
Java 8로 다음과 같이 표현할 수 있다.
String fromFile = new BufferedReader(new
InputStreamReader(inputStream)).lines().reduce(String::concat).get();
다음은 새로운 Stream API를 사용하여 모든 라인을 수집하는 Java 8 기반 솔루션 입니다.InputStream
:
public static String toString(InputStream inputStream) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
return reader.lines().collect(Collectors.joining(
System.getProperty("line.separator")));
}
'programing' 카테고리의 다른 글
Vue: v-for에서 메소드를 사용하지만 Getter가 준비되지 않음 (0) | 2022.04.18 |
---|---|
문자열의 해시 함수 (0) | 2022.04.18 |
VueJ를 사용하여 테이블에서 행 제거s (0) | 2022.04.18 |
어떻게 gcc가 C의 일부 문구를 최적화하는 것을 방지할 수 있는가? (0) | 2022.04.18 |
왜 변수 이름들은 종종 'm'자로 시작하는가? (0) | 2022.04.18 |