java InputStream能否从方法中连续读取数据?
我有一段代码java InputStream能否从方法中连续读取数据?,java,io,Java,Io,我有一段代码 ... InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream("test".getBytes())); ... 这一行使字符串“test”成为InputStream的输入,然而这是一个静态InputStream。 在没有扫描仪、System.in或用户外部输入的情况下,是否有办法使此InputStream动态 我需要的是这样的东西 ... InputStream i
...
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(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”的方法中,这就是您的实现 您有两个主要选择: 线程 相反,您可以启动一个不断生成数据的线程。请注意,它“生成”的任何内容都需要缓存;例如,如果您想要动态生成一个只提供无限量的0字节的inputstream,那么这不是一个好的匹配。如果数据来自(比如)一个USB连接的arduino,它会时不时地发送它所连接的温度传感器的信息,这是一个很好的选择。注意,您需要线程将它接收到的数据存储到某个地方,然后有一个inputstream,它将从您正在生成的数据队列中“拉入”。要生成从队列中提取的inputstream,请参阅下一节。由于这将涉及线程,请使用
java.util.concurrent
中的一些内容,例如-这有双重好处,即您也不会得到无限的缓冲区(如果缓冲区已满,则将某些内容放入缓冲区的行为将被阻止)
子类化
你也可以做的是把能生成新值的代码放在信封里——你可以把它传递出去。您希望生成一些代码,但不运行它-您希望稍后在将inputstream交给的对象调用.read()
时运行它
一种简单的方法是扩展InputStream,然后实现自己的zero方法。看起来像这样:
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.
}
你想要个烟斗。具体来说,您需要以下一对类:
- 及
- 及
getBytes()
将在Windows系统上返回与非Windows系统不同的值。使用读写器将消除对此的担忧
无论哪种方式,方法都是相同的:创建管道的可读端,然后创建管道的可写端并将其送入另一个线程
使用PipedWriter和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;
}
PipedReader PipedReader=新的PipedReader();
读卡器=新的BufferedReader(pipedReader);
ExecutorService executor=Executors.newSingleThreadExecutor();
Future pipeFeeder=executor.submit(
()->generateContinuousDynamicString(pipedReader));
// ...
私有Void generateContinuousDynamicString(PipedReader PipedReader)
抛出IOException{
try(Writer-Writer=newpipedwriter(pipedReader)){
作者:写(“”);
对于(int i=0;i<1000;i++){
writer.write(“+i+”);
}
作者:写(“”);
}
返回null;
}
使用PipedInputStream和PipedOutStream:
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;
}
PipedInputStream PipedInputStream=new PipedInputStream();
InputStream InputStream=新的BufferedInputStream(pipedInputStream);
ExecutorService executor=Executors.newSingleThreadExecutor();
Future pipeFeeder=executor.submit(
()->generateContinuousDynamicString(pipedInputStream));
// ...
私有Void generateContinuousDynamicString(PipedInputStream PipedInputStream)
抛出IOException{
Charset Charset=StandardCharsets.UTF_8;
try(Writer-Writer=newoutputstreamwriter(
新的PipedInputStream(PipedInputStream),
标准字符集(UTF_8)){
作者:写(“”);
对于(int i=0;i<1000;i++){
writer.write(“+i+”);
}
作者:写(“”);
}
返回null;
}
谢谢您的回答。是否有可能获得与管道提供的功能相同的功能,但没有任何额外的线程或线程是必须的?如果您希望通过读取器或InputStream获得数据,则需要单独的线程。您也可以使用ByteArrayInputStream或StringReader,就像您已经在做的那样,但这需要提前生成所有内容,如果内容太多,您的程序可能会发现内存不足。