리더를 InputStream으로, 라이터를 OutputStream으로 변환하는 방법
텍스트 인코딩 문제를 쉽게 해결할 수 있는 방법이 있습니까?
String으로 시작하는 경우 다음 작업도 수행할 수 있습니다.
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
텍스트 인코딩 문제를 피할 수 없지만 Apache Commons에는 다음과 같은 기존 솔루션이 있습니다.
Reader
로로 합니다.InputStream
다음과 같습니다.Writer
로로 합니다.OutputStream
다음과 같습니다.
원하는 인코딩을 선택하면 됩니다.
리더는 문자를 다루고 InputStream은 바이트를 처리합니다.인코딩은 문자를 바이트로 표시하는 방법을 지정하기 때문에 이 문제를 무시할 수 없습니다.문제를 회피하기 위해서라면, 1개의 문자 집합(예를 들면 「UTF-8」)을 선택해, 그대로 해 두는 것이 제 의견입니다.
실제로 실시하는 방법에 대해서는, 지적한 대로, 「이러한 클래스의 이름은 ReaderInputStream과 WriterOutputStream」입니다.놀랍게도 '반대' 클래스, InputStreamReader 및 OutputStreamWriter가 포함되어 있는데도 "이러한 클래스들은 Java 라이브러리에 포함되어 있지 않습니다."
그래서 Apache Commons IO를 포함한 많은 사람들이 그들만의 구현을 생각해냈습니다.라이센스 문제에 따라서는, 프로젝트에 commons-io 라이브러리를 포함하거나, 소스 코드의 일부(여기서 다운로드 가능)를 카피할 수 있습니다.
보시는 바와 같이 두 클래스의 문서에는 "JRE에서 지원되는 모든 문자 집합 인코딩은 올바르게 처리됩니다"라고 기재되어 있습니다.
N.B. 여기 다른 답변 중 하나에 대한 댓글에 이 버그가 언급되어 있습니다.그러나 이는 Apache Commons IO ReaderInputStream 클래스가 아닌 Apache Ant ReaderInputStream 클래스(여기서)에 영향을 미칩니다.
또한 String으로 시작하는 경우 StringReader 작성을 건너뛰고 org.apache.commons.io을 사용하여 InputStream을 한 번에 작성할 수 있습니다.Commons IO로부터의 IOTils는 다음과 같습니다.
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
물론 텍스트 인코딩에 대해서도 생각해 볼 필요가 있지만 적어도 변환은 한 번에 이루어집니다.
용도:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
됩니다.String
나서 그음음 and andbyte[]
보고서가 큰 경우에 대비하여 훨씬 더 많은 힙메모리를 할당합니다.String Buffer를 선택합니다.
Apache Commons IO 프로젝트의 CharSequenceInputStream을 사용합니다.
이러한 클래스의 명확한 이름은 ReaderInputStream과 WriterOutputStream입니다.유감스럽게도 이것들은 Java 라이브러리에 포함되어 있지 않습니다.하지만 구글은 당신의 친구입니다.
악몽 같은 텍스트 인코딩 문제를 모두 해결할 수 있을지는 잘 모르겠습니다.
RFE는 있지만 Closed 상태이므로 수정되지 않습니다.
텍스트 인코딩 문제를 피할 수 없지만 Apache commons-io는
이것들은, koders.com 의 피터의 회답에 기재되어 있는 라이브러리이며, 소스코드 대신에 라이브러리에의 링크에 지나지 않습니다.
of of of의 내용을 하는 요?Reader
OutputStream
이 경우 포장하는 데 시간이 걸립니다.OutputStream
an 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 라이브러리의 일부가 아닌 이유는 텍스트를 바이트로 변환하는 것보다 훨씬 신뢰성이 높습니다.
이것은 간단한 UTF-8 기반 인코딩 WriterOutputStream 및 ReaderInputStream 소스 코드입니다.마지막에 테스트 완료.
// https://www.woolha.com/tutorials/deno-utf-8-encoding-decoding-examples
public class WriterOutputStream extends OutputStream {
final Writer writer;
int count = 0;
int codepoint = 0;
public WriterOutputStream(Writer writer) {
this.writer = writer;
}
@Override
public void write(int b) throws IOException {
b &= 0xFF;
switch (b >> 4) {
case 0b0000:
case 0b0001:
case 0b0010:
case 0b0011:
case 0b0100:
case 0b0101:
case 0b0110:
case 0b0111:
count = 1;
codepoint = b;
break;
case 0b1000:
case 0b1001:
case 0b1010:
case 0b1011:
codepoint <<= 6;
codepoint |= b & 0b0011_1111;
break;
case 0b1100:
case 0b1101:
count = 2;
codepoint = b & 0b0001_1111;
break;
case 0b1110:
count = 3;
codepoint = b & 0b0000_1111;
break;
case 0b1111:
count = 4;
codepoint = b & 0b0000_0111;
break;
}
if (--count == 0) {
writer.write(codepoint);
}
}
}
public class ReaderInputStream extends InputStream {
final Reader reader;
int count = 0;
int codepoint;
public ReaderInputStream(Reader reader) {
this.reader = reader;
}
@Override
public int read() throws IOException {
if (count-- > 0) {
int r = codepoint >> (count * 6);
r &= 0b0011_1111;
r |= 0b1000_0000;
return r;
}
codepoint = reader.read();
if (codepoint < 0)
return -1;
if (codepoint > 0xFFFF)
return 0;
if (codepoint < 0x80)
return codepoint;
if (codepoint < 0x800) {
count = 1;
int v = (codepoint >> 6) | 0b1100_0000;
return v;
}
count = 2;
int v = (codepoint >> 12) | 0b1110_0000;
return v;
}
}
65536 문자의 각 문자가 올바르게 부호화 및 복호화되어 있는지 여부를 검증하는 테스트 케이스와 Java 부호화와 일치하는지 검증합니다.대리 검증(2 문자 인코딩)은 Java에서 처리되므로 무시됩니다.
@Test
public void testAll() throws IOException {
for (char i = 0; i < 0xFFFF; i++) {
CharArrayReader car = new CharArrayReader(new char[] { i });
ReaderInputStream rtoi = new ReaderInputStream(car);
byte[] data = IO.read(rtoi);
CharArrayWriter caw = new CharArrayWriter();
try (WriterOutputStream wtoo = new WriterOutputStream(caw)) {
wtoo.write(data);
char[] translated = caw.toCharArray();
assertThat(translated.length).isEqualTo(1);
assertThat((int) translated[0]).isEqualTo(i);
if (!Character.isSurrogate((char) i)) {
try (InputStream stream = new ByteArrayInputStream(data)) {
caw = new CharArrayWriter();
IO.copy(data, caw);
translated = caw.toCharArray();
assertThat(translated.length).isEqualTo(1);
assertThat((int) translated[0]).isEqualTo(i);
}
}
}
}
}
java가 제공하는 것을 사용하여 스트림 내의 문자열을 읽는 경우.
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));
언급URL : https://stackoverflow.com/questions/62241/how-to-convert-a-reader-to-inputstream-and-a-writer-to-outputstream
'programing' 카테고리의 다른 글
창 크기 조정 시 v-navigation이 런어웨이 루프로 떨어짐 (0) | 2023.01.31 |
---|---|
재스트를 사용하여 Vue.js 컴포넌트의 메서드를 유닛 테스트하는 방법 (0) | 2023.01.31 |
move_movel_file은 "오픈 스트림에 대한 접근:권한 거부" 오류 (0) | 2023.01.31 |
1부터 시작하는 숫자 범위를 열거하는 방법 (0) | 2023.01.31 |
Vue - 여러 확인란이 있는 입력 (0) | 2023.01.31 |