生成输入流的资源有效方式是什么?
What is the resource efficient way to generate 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);
也许,我误解了什么,但是除了使用 getBytes()
之外,还有更好的方法从 String 生成 InputStream
吗?
例如,如果 String 真的很大,有 50MB,并且由于资源限制而无法创建它的另一个副本(getBytes() 用于另一个 50MB),它可能会引发内存不足错误。
我只是想知道上面的代码行是否是从字符串生成 InputStream
的有效方法。例如,有没有一种方法可以 "stream" String 进入输入流而不使用额外的内存?就像在 String 之上的类似 Reader
的抽象?
尝试这样的事情(不保证打字错误:)
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 允许您读取字符块。
对于非常大的输入流,您可能希望分块处理输入,而不是将整个流读入内存然后进行处理。
我认为您要查找的是 StringReader,其定义为:
A character stream whose source is a string.
要有效地使用它,您需要确切地知道您希望读取的字节所在的位置。它支持随机和顺序访问,因此如果您愿意,您可以通过 char
阅读整个 String
、char
。
您正在生成数据,实际上是 写入 并且您想几乎立即使用数据,读取。
Unix 技术是将一个进程的输出通过管道传输到另一个进程的输入。在 java 中,至少还需要两个线程。他们将同步生产和消费。
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
new Thread(() -> writeAllYouveGot(out)).start();
readAllYouveGot(in);
在这里,我启动了一个用于编写的线程,它使用一个在 out
上调用一些自定义方法的 Runnable。而不是使用 new Thread
你可能更喜欢 ExecutorService.
管道 I/O 很少使用,尽管异步行为是最佳的。甚至可以在 PipedInputStream 上设置管道的大小。很少使用的原因是需要第二个线程。
为了完成事情,人们可能会将二进制 Input/OutputStreams 包装在 new InputStreamReader(in, "UTF-8")
和 new OutputStreamWriter(out, "UTF-8")
.
中
我是 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);
也许,我误解了什么,但是除了使用 getBytes()
之外,还有更好的方法从 String 生成 InputStream
吗?
例如,如果 String 真的很大,有 50MB,并且由于资源限制而无法创建它的另一个副本(getBytes() 用于另一个 50MB),它可能会引发内存不足错误。
我只是想知道上面的代码行是否是从字符串生成 InputStream
的有效方法。例如,有没有一种方法可以 "stream" String 进入输入流而不使用额外的内存?就像在 String 之上的类似 Reader
的抽象?
尝试这样的事情(不保证打字错误:)
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 允许您读取字符块。
对于非常大的输入流,您可能希望分块处理输入,而不是将整个流读入内存然后进行处理。
我认为您要查找的是 StringReader,其定义为:
A character stream whose source is a string.
要有效地使用它,您需要确切地知道您希望读取的字节所在的位置。它支持随机和顺序访问,因此如果您愿意,您可以通过 char
阅读整个 String
、char
。
您正在生成数据,实际上是 写入 并且您想几乎立即使用数据,读取。
Unix 技术是将一个进程的输出通过管道传输到另一个进程的输入。在 java 中,至少还需要两个线程。他们将同步生产和消费。
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
new Thread(() -> writeAllYouveGot(out)).start();
readAllYouveGot(in);
在这里,我启动了一个用于编写的线程,它使用一个在 out
上调用一些自定义方法的 Runnable。而不是使用 new Thread
你可能更喜欢 ExecutorService.
管道 I/O 很少使用,尽管异步行为是最佳的。甚至可以在 PipedInputStream 上设置管道的大小。很少使用的原因是需要第二个线程。
为了完成事情,人们可能会将二进制 Input/OutputStreams 包装在 new InputStreamReader(in, "UTF-8")
和 new OutputStreamWriter(out, "UTF-8")
.