[java] IOUtils.toString (InputStream)에 해당하는 Guava

Apache Commons IO 에는 문자열 을 읽을 수있는 편리한 메서드 IOUtils.toString ()InputStream있습니다.

Apache Commons에서 Guava 로 이동하려고하므로 Guava 에 동등한 기능이 있습니까? com.google.common.io패키지의 모든 클래스를 살펴 보았지만 거의 간단한 것을 찾을 수 없었습니다.

편집 : 나는 문자 세트와 관련된 문제를 이해하고 감사합니다. 내 모든 소스가 ASCII (예, ​​ASCII, ANSI 등이 아님)라는 것을 알고 있으므로이 경우 인코딩은 문제가되지 않습니다.



답변

Calum의 답변에 대한 귀하의 의견에서 사용할 예정이라고 말했습니다.

CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))

이 코드는 과부하 CharStreams.toString(Readable)상태로 인해 문제가 됩니다.

을 닫습니다하지 않습니다 Readable.

InputStreamReader, 이 코드가 완료된 후에도 에서 InputStream반환 된 supplier.get()이 (가) 닫히지 않습니다.

반면에 이미있는 것으로 보이며 InputSupplier<InputStream>오버로드를 사용 했다는 사실을 활용 CharStreams.toString(InputSupplier<R extends Readable & Closeable>하면 toString메서드가의 생성과 종료를 모두 처리 Reader합니다.

이것은 어떤 과부하 사실이없는 것을 제외하고 존 소총이 제안 정확히 무엇을 CharStreams.newReaderSupplier하는가 소요 InputStream입력으로 … 당신은 그것을에게주고 있습니다 InputSupplier:

InputSupplier<? extends InputStream> supplier = ...
InputSupplier<InputStreamReader> readerSupplier =
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8);

// InputStream and Reader are both created and closed in this single call
String text = CharStreams.toString(readerSupplier);

요점은 InputSupplierGuava가 추악한 try-finally블록 이 필요한 부품을 처리하여 리소스가 제대로 닫히 도록함으로써 삶을 더 쉽게 만드는 것입니다.

편집 : 개인적으로 다음을 찾습니다 (실제로 작성하는 방법은 위 코드의 단계를 분해하는 것입니다)

String text = CharStreams.toString(
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));

일하기 훨씬 덜 장황 이보다 :

String text;
InputStreamReader reader = new InputStreamReader(supplier.get(),
    Charsets.UTF_8);
boolean threw = true;
try {
  text = CharStreams.toString(reader);
  threw = false;
}
finally {
  Closeables.close(reader, threw);
}

이 문제를 직접 처리하기 위해 작성해야 할 내용은 어느 정도입니다.


편집 : 2014 년 2 월

InputSupplier그리고 OutputSupplier이를 사용하는 방법은 Guava 16.0에서 더 이상 사용되지 않습니다. 이들의 교체는 ByteSource, CharSource, ByteSinkCharSink. 가 주어지면 ByteSource이제 다음 String과 같은 내용을 얻을 수 있습니다 .

ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();


답변

당신이 가지고있는 경우에 Readable당신은 사용할 수 있습니다 CharStreams.toString(Readable). 따라서 다음을 수행 할 수 있습니다.

String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );

어쨌든 당신이해야 할 문자 세트를 지정하도록 강요합니다.


답변

업데이트 : 돌아 보면, 나는 내 오래된 솔루션이 마음에 들지 않습니다. 게다가 지금은 2013 년이고 Java7에 대한 더 나은 대안이 있습니다. 그래서 여기 내가 지금 사용하는 것이 있습니다.

InputStream fis = ...;
String text;
try (  InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){
        text = CharStreams.toString(reader);
}

또는 InputSupplier를 사용하는 경우

InputSupplier<InputStreamReader> spl = ...
try (  InputStreamReader reader = spl.getInput()){
        text = CharStreams.toString(reader);
    }


답변

거의. 다음과 같이 사용할 수 있습니다.

InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
    (streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);

개인적으로 나는 그것이 “좋은” 것이라고 생각 하지 않는다.IOUtils.toString(InputStream) 왜냐하면 그것은 항상 플랫폼의 기본 인코딩을 사용하기 때문이다. 이것은 거의 당신이 원하는 것이 아니다. 인코딩 이름을 사용하는 과부하가 있지만 이름을 사용하는 것은 IMO에서 좋은 생각이 아닙니다. 그것이 내가 좋아하는 이유 Charsets.*입니다.

편집 : 위 InputSupplier<InputStream>streamSupplier. 이미 스트림이 있다면 쉽게 구현할 수 있습니다.

InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
    @Override public InputStream getInput() {
        return stream;
    }
};


답변

또 다른 옵션은 Stream에서 바이트를 읽고 여기에서 문자열을 만드는 것입니다.

new String(ByteStreams.toByteArray(inputStream))
new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)

‘순수한’구아바는 아니지만 조금 더 짧습니다.


답변

받아 들여진 대답을 바탕으로 여기에 IOUtils.toString()(및 문자 집합이있는 오버로드 된 버전) 동작을 조롱하는 유틸리티 메서드가 있습니다. 이 버전은 안전해야합니다. 그렇죠?

public static String toString(final InputStream is) throws IOException{
    return toString(is, Charsets.UTF_8);
}


public static String toString(final InputStream is, final Charset cs)
throws IOException{
    Closeable closeMe = is;
    try{
        final InputStreamReader isr = new InputStreamReader(is, cs);
        closeMe = isr;
        return CharStreams.toString(isr);
    } finally{
        Closeables.closeQuietly(closeMe);
    }
}


답변

입력 스트림이 클래스 경로 리소스에서 오는 경우 훨씬 더 짧은 자동 닫기 솔루션이 있습니다.

URL resource = classLoader.getResource(path);
byte[] bytes = Resources.toByteArray(resource);
String text = Resources.toString(resource, StandardCharsets.UTF_8);

IOExplained 에서 영감을받은 Guava Resources를 사용합니다 .