什么是资源有效的方式来生成输入流?

时间:2017-07-12 19:24:21

标签: java inputstream

我是Java IO的新手。目前,我有这些代码行,它们根据字符串生成输入流。

String sb = new StringBuilder();
for(...){
   sb.append(...);
}
String finalString = sb.toString();
byte[] objectBytes = finalString.getBytes(StandardCharsets.UTF_8);
InputStream inputStream = new ByteArrayInputStream(objectBytes);

也许,我误解了一些东西,但除了使用InputStream之外,还有更好的方法从String生成getBytes()吗?

例如,如果String非常大,50MB,并且由于资源限制,无法为其创建另一个副本(另外50MB的getBytes()),它可能会引发内存不足错误。

我只是想知道上面的代码行是否是从String生成InputStream的有效方法。例如,有没有一种方法我可以"流"串入输入流而不使用额外的内存?像Reader一样 - 在String之上的抽象?

3 个答案:

答案 0 :(得分:3)

我认为您正在寻找的是documentation,其定义为:

  

源为字符串的字符流。

要有效地使用它,您需要确切地知道您希望读取的字节位置。它支持随机和顺序访问,因此如果您愿意,可以按String阅读整个charchar

答案 1 :(得分:0)

您正在生成数据,实际上正在编写,并且您希望几乎立即使用读取数据。

Unix技术是将一个进程的输出传递给另一个进程的输入。在java中,还需要至少两个线程。他们将在生产和消费上同步。

PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
new Thread(() -> writeAllYouveGot(out)).start();
readAllYouveGot(in);

在这里,我开始使用Runnable编写一个Thread,在out上调用一些自定义方法。您可能不喜欢使用new Thread,而是使用ExecutorService

虽然异步行为是最佳的,但很少使用管道I / O.甚至可以在PipedInputStream上设置管道的大小。这种罕见用法的原因是需要第二个线程。

要完成任务,可能会将二进制Input / OutputStream包装在new InputStreamReader(in, "UTF-8")new OutputStreamWriter(out, "UTF-8")中。

答案 2 :(得分:-1)

尝试这样的事情(没有关于拼写错误的承诺:)。

BufferedReader reader = new BufferedRead(new InputStreamReader(yourInputStream), Charset.defaultCharset());
final char[] buffer = new char[8000];
int charsRead = 0;
while(true) {
    charsRead = reader.read(buffer, 0, 8000);
    if (charsRead == -1) {
        break;
    }
    // Do something with buffer
}

InputStreamReader使用Charset从byte转换为char。 BufferedReader允许您读取char块。

对于非常大的输入流,您可能希望以块的形式处理输入,而不是将整个流读入内存然后进行处理。