任何使用大型String并返回InputStream的util类/方法?

时间:2015-01-12 18:51:27

标签: java string inputstream

我正在寻找一些实用的类{/ 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中流出字节。

我似乎没有其他人在寻找这样的东西。我在某个地方误解了什么吗?

我已经开始为此编写一个自定义类,但如果有更好/正确/正确的解决方案/更正我的需要会停止。

2 个答案:

答案 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方法添加到此实现中。