Reader를 InputStream으로, Writer를 OutputStream으로 변환하는 방법은 무엇입니까?


답변:


45

텍스트 인코딩 문제를 처리하는 것을 실제로 피할 수는 없지만 Apache Commons에는 기존 솔루션이 있습니다.

원하는 인코딩을 선택하기 만하면됩니다.


7
참고 : ReaderInputStream 코드에는 바이트를 읽는 방식에 버그가 있습니다 (모든 인코딩에서 작동하지 않음). 증명 : illegalargumentexception.blogspot.com/2009/05/… 공개 버그가 있습니다 : issues.apache.org/bugzilla/show_bug.cgi?id=40455
McDowell

1
당신은 아파치의 평민-IO 라이브러리의 클래스를 찾을 수 있습니다 commons.apache.org/proper/commons-io
AlikElzin-kilaka

@McDowell, 당신이 언급 한 버그는 commons-io가 아닌 Apache Ant의 구현에 있으므로이 답변과 관련이 없습니다.
Roman

94

문자열로 시작하는 경우 다음을 수행 할 수도 있습니다.

new ByteArrayInputStream(inputString.getBytes("UTF-8"))

7
좋은 ReaderInputStream구현은 더 적은 메모리를 필요로합니다. 모든 바이트를 한 번에 배열에 저장할 필요가 없습니다.
Piotr Findeisen

3
이 솔루션은 표준 입력에 대한 입력을 허용하는 단위 테스트 코드가 필요할 때 작동합니다.
Kedar Mhaswade

43

글쎄, 리더는 문자를 처리하고 InputStream은 바이트를 처리합니다. 인코딩은 문자를 바이트로 표현하는 방법을 지정하므로 문제를 무시할 수 없습니다. 문제를 피하는 것과 관련하여 제 의견은 하나의 문자 집합 (예 : "UTF-8")을 선택하고 그대로 유지하는 것입니다.

실제로 수행하는 방법과 관련하여 지적했듯이 " 이러한 클래스의 명백한 이름은 ReaderInputStreamWriterOutputStream 입니다. "놀랍게도 " 이들은 '반대'클래스 인 InputStreamReaderOutputStreamWriter Java 라이브러리에 포함되어 있지 않습니다 . " 포함.

그래서 많은 사람들이 Apache Commons IO를 포함한 자체 구현을 생각해 냈습니다 . 라이선스 문제에 따라 프로젝트에 commons-io 라이브러리를 포함하거나 소스 코드의 일부를 복사 할 수도 있습니다 ( 여기에서 다운로드 가능 ).

보시다시피 두 클래스의 문서에는 "JRE에서 지원하는 모든 문자 집합 인코딩이 올바르게 처리됩니다"라고 나와 있습니다.

NB 여기에있는 다른 답변 중 하나에 대한 의견은 이 버그를 언급 합니다 . 그러나 이는 Apache Commons IO ReaderInputStream 클래스가 아닌 Apache Ant ReaderInputStream 클래스 ( 여기 )에 영향을줍니다 .


19

또한 문자열로 시작하는 경우 다음 과 같이 Commons IO 에서 org.apache.commons.io.IOUtils를 사용하여 StringReader 생성을 건너 뛰고 한 단계로 InputStream을 생성 할 수 있습니다 .

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

물론 텍스트 인코딩에 대해 생각할 필요가 있지만 적어도 변환은 한 단계에서 발생합니다.


4
이 방법은 기본적으로 new ByteArrayInputStream(report.toString().getBytes("utf-8"))두 개의 추가 보고서 사본을 메모리에 할당하는 작업을 수행합니다. 보고서가 크면 나쁜 것입니다. 내 대답을 참조하십시오.
Oliv

8

사용하다:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

이 방법에 대한 선행 변환이 필요하지 않습니다 String다음에 byte[]보고서가 큰 경우, 할당 더 많은 힙 메모리를. StringBuffer에서 바로 스트림을 읽을 때 즉석에서 바이트로 변환합니다.

Apache Commons IO 프로젝트의 CharSequenceInputStream 을 사용합니다 .



5

이러한 클래스의 분명한 이름은 ReaderInputStream 및 WriterOutputStream입니다. 불행히도 이들은 Java 라이브러리에 포함되어 있지 않습니다. 그러나 Google은 당신의 친구입니다.

악몽 같은 모든 텍스트 인코딩 문제를 해결할 수 있을지 모르겠습니다.

RFE가 있지만 Closed이며 수정되지 않습니다.


1
bugs.openjdk.java.net/browse/JDK-4103785 에는 "문자 집합 코딩을위한 공용 API가 있습니다. 이러한 클래스를 추가 할 설득력있는 이유가 없습니다."라는 주석이 포함되어 있습니다. 따라서 추가없이 Java 7에서이를 수행하는 방법 12 년 뒤에 도서관?
Piotr Findeisen


4

당신은의 내용을 작성하려고 Reader에를 OutputStream? 그렇다면, 당신은 쉽게 시간을 포장해야합니다 OutputStream의를 OutputStreamWriter하고, 쓰기 char으로부터의를 Reader받는 Writer대신에 독자를 변환하기 위해 노력하는, InputStream:

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block

1

WriterOutputStream 사용시 경고-파일에 바이너리 데이터 쓰기를 항상 적절하게 / 일반 출력 스트림과 동일하게 처리하지는 않습니다. 나는 이것을 추적하는 데 시간이 걸리는 문제가있었습니다.

가능하다면 출력 스트림을 기본으로 사용하는 것이 좋으며 문자열을 작성해야하는 경우 스트림 주위에 OUtputStreamWriter 래퍼를 사용하여 수행하는 것이 좋습니다. 다른 방법보다 텍스트를 바이트로 변환하는 것이 훨씬 더 안정적이므로 WriterOutputStream이 표준 Java 라이브러리의 일부가 아닌 것 같습니다.



-1

Java가 제공하는 것을 사용하여 스트림에서 문자열을 읽는 경우.

InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));

6
ReaderInputStream은 Apache Commons IO에 있습니다.
Will Beason
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.