나는이 String
내가으로 사용하도록을 InputStream
. Java 1.0에서는를 사용할 수 java.io.StringBufferInputStream
있지만 그랬습니다 @Deprecrated
(좋은 이유가 있습니다. 문자 집합 인코딩을 지정할 수 없음).
이 클래스는 문자를 바이트로 올바르게 변환하지 않습니다. JDK 1.1부터 문자열에서 스트림을 만드는 데 선호되는 방법은
StringReader
클래스를 사용하는 것입니다.
당신은 만들 수 java.io.Reader
와를 java.io.StringReader
하지만을 할 어댑터가없는 Reader
과를 만들 수는 InputStream
.
적절한 교체를 요구 하는 오래된 버그를 찾았 지만, 내가 말할 수있는 한 그런 것은 존재하지 않습니다.
자주 제안되는 해결 방법은 다음에 대한 java.lang.String.getBytes()
입력으로 사용 하는 것입니다 java.io.ByteArrayInputStream
.
public InputStream createInputStream(String s, String charset)
throws java.io.UnsupportedEncodingException {
return new ByteArrayInputStream(s.getBytes(charset));
}
그러나 그것은 String
메모리 의 전체 를 바이트 배열로 구체화하는 것을 의미 하며 스트림의 목적을 무효화합니다. 대부분의 경우 이것은 큰 문제는 아니지만 스트림의 의도를 보존 할 수있는 무언가를 찾고있었습니다. 가능한 한 적은 양의 데이터가 메모리에 (재) 구체화되는 것입니다.
답변
업데이트 : 이 답변은 OP가 원하지 않는 것입니다. 다른 답변을 읽으십시오.
메모리에서 다시 구체화되는 데이터에 대해 신경 쓰지 않는 경우 다음을 사용하십시오.
new ByteArrayInputStream(str.getBytes("UTF-8"))
답변
commons-io 패키지 에 대한 종속성이 마음에 들지 않으면 IOUtils.toInputStream (String text) 메서드를 사용할 수 있습니다 .
답변
Reader에서 InputStream으로 조정되는 Apache Commons-IO의 어댑터가 있습니다 . 이는 ReaderInputStream 이라는 이름 입니다 .
예제 코드 :
@Test
public void testReaderInputStream() throws IOException {
InputStream inputStream = new ReaderInputStream(new StringReader("largeString"), StandardCharsets.UTF_8);
Assert.assertEquals("largeString", IOUtils.toString(inputStream, StandardCharsets.UTF_8));
}
답변
내 생각에 가장 쉬운 방법은 Writer를 통해 데이터를 푸시하는 것입니다.
public class StringEmitter {
public static void main(String[] args) throws IOException {
class DataHandler extends OutputStream {
@Override
public void write(final int b) throws IOException {
write(new byte[] { (byte) b });
}
@Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
@Override
public void write(byte[] b, int off, int len)
throws IOException {
System.out.println("bytecount=" + len);
}
}
StringBuilder sample = new StringBuilder();
while (sample.length() < 100 * 1000) {
sample.append("sample");
}
Writer writer = new OutputStreamWriter(
new DataHandler(), "UTF-16");
writer.write(sample.toString());
writer.close();
}
}
JVM 구현은 8K 청크로 푸시 된 데이터를 사용하고 있지만 한 번에 쓰는 문자 수를 줄이고 flush를 호출하여 버퍼 크기에 영향을 줄 수 있습니다.
Writer를 사용하여 데이터를 인코딩하는 자체 CharsetEncoder 래퍼를 작성하는 대신 올바른 작업을 수행하는 것은 다소 고통 스럽습니다. 이것은 신뢰할 수있는 (비효율적 인 경우) 구현이어야합니다.
/** Inefficient string stream implementation */
public class StringInputStream extends InputStream {
/* # of characters to buffer - must be >=2 to handle surrogate pairs */
private static final int CHAR_CAP = 8;
private final Queue<Byte> buffer = new LinkedList<Byte>();
private final Writer encoder;
private final String data;
private int index;
public StringInputStream(String sequence, Charset charset) {
data = sequence;
encoder = new OutputStreamWriter(
new OutputStreamBuffer(), charset);
}
private int buffer() throws IOException {
if (index >= data.length()) {
return -1;
}
int rlen = index + CHAR_CAP;
if (rlen > data.length()) {
rlen = data.length();
}
for (; index < rlen; index++) {
char ch = data.charAt(index);
encoder.append(ch);
// ensure data enters buffer
encoder.flush();
}
if (index >= data.length()) {
encoder.close();
}
return buffer.size();
}
@Override
public int read() throws IOException {
if (buffer.size() == 0) {
int r = buffer();
if (r == -1) {
return -1;
}
}
return 0xFF & buffer.remove();
}
private class OutputStreamBuffer extends OutputStream {
@Override
public void write(int i) throws IOException {
byte b = (byte) i;
buffer.add(b);
}
}
}
답변
가능한 한 가지 방법은 다음과 같습니다.
- 만들기
PipedOutputStream
- 파이프를
PipedInputStream
OutputStreamWriter
주위를 감싸 십시오PipedOutputStream
(생성자에서 인코딩을 지정할 수 있습니다)- Et voilá,에 작성하는 모든
OutputStreamWriter
내용은PipedInputStream
!
물론 이것은 그것을하기위한 다소 험난한 방법처럼 보이지만 적어도 그것은 방법입니다.
답변
해결책은 필요에 따라 각각 또는 청크 를 바이트 배열 로 인코딩하는 데 InputStream
사용할 구현을 만드는 것입니다 .java.nio.charset.CharsetEncoder
char
char
InputStream
답변
org.hsqldb.lib 라이브러리의 도움을받을 수 있습니다.
public StringInputStream(String paramString)
{
this.str = paramString;
this.available = (paramString.length() * 2);
}