我正在寻找一些实用的类{/ 1}来获取大String
并返回InputStream
。
如果String
很小,我可以这样做:
InputStream is = new ByteArrayInputStream(str.getBytes(<charset>));
但是当String
很大(1MB,10MB或更多)时,一个字节数组就像我的String一样大到现场分配的1到2倍(或更多?)。 (并且由于你不知道在完成所有编码之前准确分配了多少字节,我认为在分配最后一个字节数组之前必须分配其他数组/缓冲区。)
我有性能要求,并希望优化此操作。
理想情况下,我认为,我正在寻找的类/方法会在使用InputStream时一次编码一个小块的字符,因此没有大量的内存分配。
查看apache commons IOUtils.toInputStream(..)
的源代码,我发现它还可以一次性将String转换为一个大字节数组。
并且StringBufferInputStream
已弃用,并且无法正常完成工作。
是否有这样的工具类/方法?或者我可以写几行代码来做到这一点?
对此的功能需求是,在其他地方,我使用的是一个带有InputStream
的util方法,并从此InputStream
中流出字节。
我似乎没有其他人在寻找这样的东西。我在某个地方误解了什么吗?
我已经开始为此编写一个自定义类,但如果有更好/正确/正确的解决方案/更正我的需要会停止。
答案 0 :(得分:0)
如果您将大字符串作为参数传递,则已分配内存。一个很大的字符串甚至不能被压入堆栈(大多数时候最大堆栈大小是1MB)所以这是在堆上分配只是为了将它作为参数传递。我可以看到避免这种情况的唯一方法是在磁盘上创建一个树,在您走过树时,您可以一次回流一个字符。如果您有多个大字符串可能可以在Trie或DAWG中对它们进行索引并遍历该结构。这将消除字符串之间的许多重复字符。但是,我需要更多地了解字符串代表什么以进一步提供帮助。
答案 1 :(得分:0)
实现您自己的String支持的输入流:
class StringifiedInputStream extends InputStream {
private int idx=0;
private final String str;
private final int len;
StringifiedInputStream(String str) {
this.str = str;
this.len = str.length();
}
@Override
public int read() throws IOException {
if(idx>=len)
return -1;
return (byte) str.charAt(idx++);
}
}
这很慢,但是它在没有字节数组重复的情况下传输字节。如果速度有问题,请将3-arg方法添加到此实现中。