java InputStream 可以从方法中连续读取数据吗?
Can a java InputStream continuously read data from a method?
我有一段代码
...
InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream("test".getBytes()));
...
并且此行使字符串“test”成为 InputStream 的输入,但这是一个静态 InputStream。
没有扫描仪,System.in 或用户外部输入有没有办法使这个 InputStream 动态
我需要的是这样的东西
...
InputStream inputStream = new BufferedInputStream(new
ByteArrayInputStream(generateContinuousDynamicString().getBytes()));
// So, basically input stream will be blocked until generateContinuousDynamicString()
// returns a result?
...
我试过这样的东西
private static byte[] generateContinuousDynamicString(String s) {
String t = "";
// here comes the realization
// that the source for an input stream
// cannot be generated dynamically on the
// fly it only can be read from already
// existing (fully generated and available
// resource). Am I right? Otherwise how
// can I adjust this method in such a way that
// input stream would continuously have a new
// string to read from?
for (int i = 0; i < 1000; i++){
t += "<str>"+s+i+"</str>";
}
return ("<test>"+t+"</test>").getBytes();
}
所以,如果我们有
...
InputStream inputStream = new BufferedInputStream(readFromADatabaseStream());
...
这也不是动态输入流,因为资源已经在数据库中。
当然可以。但是你有一个问题:无论什么代码正在生成无穷无尽的动态数据流,都不能仅在 'returns the inputstream' 本身的方法中,这就是你的实现。
您有两个主要选择:
线程
相反,您可以启动一个不断生成数据的线程。请注意,无论什么 'generates' 都需要缓存;这 不太合适 例如,如果您想动态生成一个只提供无限量 0 字节的输入流。如果数据来自,比如说,一个 USB 连接的 arduino,它会不时发送有关它所连接的温度传感器的信息,这是一个很好的选择。请注意,您需要线程将它接收到的数据存储在某个地方,然后有一个输入流将从您正在制作的数据队列中 'pull' 。要创建从队列中提取的输入流,请参阅下一节。由于这将涉及线程,因此使用 java.util.concurrent
中的内容,例如 ArrayBlockingQueue
- 这具有双重好处,您也不会获得无限缓冲区(将内容放入缓冲区的行为将阻塞如果缓冲区已满)。
子类化
您还可以将可以生成新值的代码放入一个信封中 - 一个您可以传递的东西。您想编写一些代码,但 而不是 运行 它 - 您想要 运行 稍后,当您将输入流交给它时,调用 .read()
.
一种简单的方法是 扩展 InputStream - 然后实现您自己的零方法。看起来像这样:
class InfiniteZeroesInputStream extends InputStream {
public int read() {
return 0;
}
}
就这么简单。给定:
try (InputStream in = new InfiniteZeroesInputStream()) {
in.read(); // returns 0.. and will always do so.
byte[] b = new byte[65536];
in.read(b); // fills the whole array with zeroes.
}
你想要一个 管道。 具体来说,你想要以下一对 类:
您的问题要求 InputStream,但由于您处理的是文本,因此您可能应该使用 Reader,它专用于字符。特别要注意的是,对于任何具有 non-ASCII 个字符。使用 Reader 和 Writer 将消除担心这一点的需要。
无论哪种方式,方法都是相同的:创建管道的可读端,然后在另一个线程中创建并提供管道的可写端。
使用 PipedReader 和 PipedWriter:
PipedReader pipedReader = new PipedReader();
Reader reader = new BufferedReader(pipedReader);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> pipeFeeder = executor.submit(
() -> generateContinuousDynamicString(pipedReader));
// ...
private Void generateContinuousDynamicString(PipedReader pipedReader)
throws IOException {
try (Writer writer = new PipedWriter(pipedReader)) {
writer.write("<test>");
for (int i = 0; i < 1000; i++) {
writer.write("<str>" + i + "</str>");
}
writer.write("</test>");
}
return null;
}
使用 PipedInputStream 和 PipedOutputStream:
PipedInputStream pipedInputStream = new PipedInputStream();
InputStream inputStream = new BufferedInputStream(pipedInputStream);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> pipeFeeder = executor.submit(
() -> generateContinuousDynamicString(pipedInputStream));
// ...
private Void generateContinuousDynamicString(PipedInputStream pipedInputStream)
throws IOException {
Charset charset = StandardCharsets.UTF_8;
try (Writer writer = new OutputStreamWriter(
new PipedInputStream(pipedinputStream),
StandardCharsets.UTF_8)) {
writer.write("<test>");
for (int i = 0; i < 1000; i++) {
writer.write("<str>" + i + "</str>");
}
writer.write("</test>");
}
return null;
}
我有一段代码
...
InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream("test".getBytes()));
...
并且此行使字符串“test”成为 InputStream 的输入,但这是一个静态 InputStream。 没有扫描仪,System.in 或用户外部输入有没有办法使这个 InputStream 动态
我需要的是这样的东西
...
InputStream inputStream = new BufferedInputStream(new
ByteArrayInputStream(generateContinuousDynamicString().getBytes()));
// So, basically input stream will be blocked until generateContinuousDynamicString()
// returns a result?
...
我试过这样的东西
private static byte[] generateContinuousDynamicString(String s) {
String t = "";
// here comes the realization
// that the source for an input stream
// cannot be generated dynamically on the
// fly it only can be read from already
// existing (fully generated and available
// resource). Am I right? Otherwise how
// can I adjust this method in such a way that
// input stream would continuously have a new
// string to read from?
for (int i = 0; i < 1000; i++){
t += "<str>"+s+i+"</str>";
}
return ("<test>"+t+"</test>").getBytes();
}
所以,如果我们有
...
InputStream inputStream = new BufferedInputStream(readFromADatabaseStream());
...
这也不是动态输入流,因为资源已经在数据库中。
当然可以。但是你有一个问题:无论什么代码正在生成无穷无尽的动态数据流,都不能仅在 'returns the inputstream' 本身的方法中,这就是你的实现。
您有两个主要选择:
线程
相反,您可以启动一个不断生成数据的线程。请注意,无论什么 'generates' 都需要缓存;这 不太合适 例如,如果您想动态生成一个只提供无限量 0 字节的输入流。如果数据来自,比如说,一个 USB 连接的 arduino,它会不时发送有关它所连接的温度传感器的信息,这是一个很好的选择。请注意,您需要线程将它接收到的数据存储在某个地方,然后有一个输入流将从您正在制作的数据队列中 'pull' 。要创建从队列中提取的输入流,请参阅下一节。由于这将涉及线程,因此使用 java.util.concurrent
中的内容,例如 ArrayBlockingQueue
- 这具有双重好处,您也不会获得无限缓冲区(将内容放入缓冲区的行为将阻塞如果缓冲区已满)。
子类化
您还可以将可以生成新值的代码放入一个信封中 - 一个您可以传递的东西。您想编写一些代码,但 而不是 运行 它 - 您想要 运行 稍后,当您将输入流交给它时,调用 .read()
.
一种简单的方法是 扩展 InputStream - 然后实现您自己的零方法。看起来像这样:
class InfiniteZeroesInputStream extends InputStream {
public int read() {
return 0;
}
}
就这么简单。给定:
try (InputStream in = new InfiniteZeroesInputStream()) {
in.read(); // returns 0.. and will always do so.
byte[] b = new byte[65536];
in.read(b); // fills the whole array with zeroes.
}
你想要一个 管道。 具体来说,你想要以下一对 类:
您的问题要求 InputStream,但由于您处理的是文本,因此您可能应该使用 Reader,它专用于字符。特别要注意的是,对于任何具有 non-ASCII 个字符。使用 Reader 和 Writer 将消除担心这一点的需要。
无论哪种方式,方法都是相同的:创建管道的可读端,然后在另一个线程中创建并提供管道的可写端。
使用 PipedReader 和 PipedWriter:
PipedReader pipedReader = new PipedReader();
Reader reader = new BufferedReader(pipedReader);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> pipeFeeder = executor.submit(
() -> generateContinuousDynamicString(pipedReader));
// ...
private Void generateContinuousDynamicString(PipedReader pipedReader)
throws IOException {
try (Writer writer = new PipedWriter(pipedReader)) {
writer.write("<test>");
for (int i = 0; i < 1000; i++) {
writer.write("<str>" + i + "</str>");
}
writer.write("</test>");
}
return null;
}
使用 PipedInputStream 和 PipedOutputStream:
PipedInputStream pipedInputStream = new PipedInputStream();
InputStream inputStream = new BufferedInputStream(pipedInputStream);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> pipeFeeder = executor.submit(
() -> generateContinuousDynamicString(pipedInputStream));
// ...
private Void generateContinuousDynamicString(PipedInputStream pipedInputStream)
throws IOException {
Charset charset = StandardCharsets.UTF_8;
try (Writer writer = new OutputStreamWriter(
new PipedInputStream(pipedinputStream),
StandardCharsets.UTF_8)) {
writer.write("<test>");
for (int i = 0; i < 1000; i++) {
writer.write("<str>" + i + "</str>");
}
writer.write("</test>");
}
return null;
}