java.lang.String에서 java.io.InputStream을 어떻게 얻을 수 있습니까?
나는이 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));
}
참조 : https://stackoverflow.com/a/27909221/5658642
내 생각에 가장 쉬운 방법은 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!
Of course, this seems like a rather hackish way to do it, but at least it is a way.
A solution is to roll your own, creating an InputStream implementation that likely would use java.nio.charset.CharsetEncoder to encode each char or chunk of chars to an array of bytes for the InputStream as necessary.
You can take help of org.hsqldb.lib library.
public StringInputStream(String paramString)
{
this.str = paramString;
this.available = (paramString.length() * 2);
}
I know this is an old question but I had the same problem myself today, and this was my solution:
public static InputStream getStream(final CharSequence charSequence) {
return new InputStream() {
int index = 0;
int length = charSequence.length();
@Override public int read() throws IOException {
return index>=length ? -1 : charSequence.charAt(index++);
}
};
}
'Programing' 카테고리의 다른 글
| std :: initializer_list가 기본 제공 언어가 아닌 이유는 무엇입니까? (0) | 2020.09.02 |
|---|---|
| Haskell 오프라인 문서? (0) | 2020.09.02 |
| 기본 메소드가있는 인터페이스는 언제 초기화됩니까? (0) | 2020.09.02 |
| CSS 수직 정렬 : 내용 전과 후 (0) | 2020.09.02 |
| 익명 함수를 정의하고 jQuery를 인수로 전달하는 이유는 무엇입니까? (0) | 2020.09.01 |