텍스트 인코딩 문제를 피할 수있는 쉬운 방법이 있습니까?
답변:
텍스트 인코딩 문제를 처리하는 것을 실제로 피할 수는 없지만 Apache Commons에는 기존 솔루션이 있습니다.
Reader
받는 사람 InputStream
:ReaderInputStream
Writer
받는 사람 OutputStream
:WriterOutputStream
원하는 인코딩을 선택하기 만하면됩니다.
문자열로 시작하는 경우 다음을 수행 할 수도 있습니다.
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
ReaderInputStream
구현은 더 적은 메모리를 필요로합니다. 모든 바이트를 한 번에 배열에 저장할 필요가 없습니다.
글쎄, 리더는 문자를 처리하고 InputStream은 바이트를 처리합니다. 인코딩은 문자를 바이트로 표현하는 방법을 지정하므로 문제를 무시할 수 없습니다. 문제를 피하는 것과 관련하여 제 의견은 하나의 문자 집합 (예 : "UTF-8")을 선택하고 그대로 유지하는 것입니다.
실제로 수행하는 방법과 관련하여 지적했듯이 " 이러한 클래스의 명백한 이름은 ReaderInputStream 및 WriterOutputStream 입니다. "놀랍게도 " 이들은 '반대'클래스 인 InputStreamReader 및 OutputStreamWriter 가 Java 라이브러리에 포함되어 있지 않습니다 . " 포함.
그래서 많은 사람들이 Apache Commons IO를 포함한 자체 구현을 생각해 냈습니다 . 라이선스 문제에 따라 프로젝트에 commons-io 라이브러리를 포함하거나 소스 코드의 일부를 복사 할 수도 있습니다 ( 여기에서 다운로드 가능 ).
보시다시피 두 클래스의 문서에는 "JRE에서 지원하는 모든 문자 집합 인코딩이 올바르게 처리됩니다"라고 나와 있습니다.
NB 여기에있는 다른 답변 중 하나에 대한 의견은 이 버그를 언급 합니다 . 그러나 이는 Apache Commons IO ReaderInputStream 클래스가 아닌 Apache Ant ReaderInputStream 클래스 ( 여기 )에 영향을줍니다 .
또한 문자열로 시작하는 경우 다음 과 같이 Commons IO 에서 org.apache.commons.io.IOUtils를 사용하여 StringReader 생성을 건너 뛰고 한 단계로 InputStream을 생성 할 수 있습니다 .
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
물론 텍스트 인코딩에 대해 생각할 필요가 있지만 적어도 변환은 한 단계에서 발생합니다.
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
두 개의 추가 보고서 사본을 메모리에 할당하는 작업을 수행합니다. 보고서가 크면 나쁜 것입니다. 내 대답을 참조하십시오.
사용하다:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
이 방법에 대한 선행 변환이 필요하지 않습니다 String
다음에 byte[]
보고서가 큰 경우, 할당 더 많은 힙 메모리를. StringBuffer에서 바로 스트림을 읽을 때 즉석에서 바이트로 변환합니다.
Apache Commons IO 프로젝트의 CharSequenceInputStream 을 사용합니다 .
이러한 클래스의 분명한 이름은 ReaderInputStream 및 WriterOutputStream입니다. 불행히도 이들은 Java 라이브러리에 포함되어 있지 않습니다. 그러나 Google은 당신의 친구입니다.
악몽 같은 모든 텍스트 인코딩 문제를 해결할 수 있을지 모르겠습니다.
RFE가 있지만 Closed이며 수정되지 않습니다.
텍스트 인코딩 문제를 피할 수는 없지만 Apache commons-io 에는
이것들은 koders.com에 대한 Peter의 답변에서 언급 된 라이브러리이며 소스 코드 대신 라이브러리에 대한 링크입니다.
당신은의 내용을 작성하려고 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
WriterOutputStream 사용시 경고-파일에 바이너리 데이터 쓰기를 항상 적절하게 / 일반 출력 스트림과 동일하게 처리하지는 않습니다. 나는 이것을 추적하는 데 시간이 걸리는 문제가있었습니다.
가능하다면 출력 스트림을 기본으로 사용하는 것이 좋으며 문자열을 작성해야하는 경우 스트림 주위에 OUtputStreamWriter 래퍼를 사용하여 수행하는 것이 좋습니다. 다른 방법보다 텍스트를 바이트로 변환하는 것이 훨씬 더 안정적이므로 WriterOutputStream이 표준 Java 라이브러리의 일부가 아닌 것 같습니다.
Cactoos 를 사용할 수 있습니다 (정적 메서드 없음, 개체 만) :
다른 방법으로도 변환 할 수 있습니다.
Java가 제공하는 것을 사용하여 스트림에서 문자열을 읽는 경우.
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));