在Java中如何快速读取不断生成的流的最新字符串?
In Java how to read the latest string of constantly generated stream fast?
在 Java 我有一个不断生成输出的进程。当然,它会被放入 out stream
(FiFo) 的某个缓冲区中,直到它被处理为止。但有时我需要的是读取最新的、实际的 string
流,就好像它是 LiFo 一样。问题是当我需要它时,我必须读取我读取之间生成的所有先前输出,因为流没有随机访问 - 这非常慢。
我用BufferedReader(StreamReader(process.getInputStream()))
BufferedReader
的缓冲区也有点问题。
如何快速丢弃不需要的所有输出?
如果可能的话,我不想创建单独的 reader-discarder 线程。
我试过了:
stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()), 1000);
然后当我需要读取输出时:
stdInput.skip(iS.available() + 1000); //get the generated up
//till now sequence length and discard it
stdInput.readLine(); //to 'flush' the BufferedReader buffer
s = stdInput.readLine(); //to read the latest string
这种方式很慢,时间不确定
我的建议(我不知道你的实现方式):https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int)
BufferedReader 有一个标记方法:
public void mark(int readAheadLimit)
throws IOException
Marks the present position in the stream. Subsequent calls to reset()
will attempt to reposition the stream to this point.
如果您知道数据的大小并且可以利用该大小将位置设置为您关心的流部分。
由于您尚未发布完整代码,因此尝试一些操作并查看哪种效果最好可能对您有用。总体而言,我不确定您会看到多少改进。
删除 BufferedReader 包装器和基准。 似乎 您的 InputStream 是内存支持的。因此读取可能便宜。如果它被缓冲 reader 可能会减慢你的速度。如果读取成本高,那么你应该保留它。
尝试 Channels.newChannel(InputStream in) and use ReadableByteChannel.read(ByteBUffer dst) 和基准测试。同样,这取决于您的 InputStream,但 Channel 可能会显示性能优势。
总体而言,我建议使用 ExecutorService 和 Callable class 进行多线程方法的读取和处理内存缓冲区。
在 Java 我有一个不断生成输出的进程。当然,它会被放入 out stream
(FiFo) 的某个缓冲区中,直到它被处理为止。但有时我需要的是读取最新的、实际的 string
流,就好像它是 LiFo 一样。问题是当我需要它时,我必须读取我读取之间生成的所有先前输出,因为流没有随机访问 - 这非常慢。
我用BufferedReader(StreamReader(process.getInputStream()))
BufferedReader
的缓冲区也有点问题。
如何快速丢弃不需要的所有输出?
如果可能的话,我不想创建单独的 reader-discarder 线程。
我试过了:
stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()), 1000);
然后当我需要读取输出时:
stdInput.skip(iS.available() + 1000); //get the generated up
//till now sequence length and discard it
stdInput.readLine(); //to 'flush' the BufferedReader buffer
s = stdInput.readLine(); //to read the latest string
这种方式很慢,时间不确定
我的建议(我不知道你的实现方式):https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int)
BufferedReader 有一个标记方法:
public void mark(int readAheadLimit)
throws IOException
Marks the present position in the stream. Subsequent calls to reset() will attempt to reposition the stream to this point.
如果您知道数据的大小并且可以利用该大小将位置设置为您关心的流部分。
由于您尚未发布完整代码,因此尝试一些操作并查看哪种效果最好可能对您有用。总体而言,我不确定您会看到多少改进。
删除 BufferedReader 包装器和基准。 似乎 您的 InputStream 是内存支持的。因此读取可能便宜。如果它被缓冲 reader 可能会减慢你的速度。如果读取成本高,那么你应该保留它。
尝试 Channels.newChannel(InputStream in) and use ReadableByteChannel.read(ByteBUffer dst) 和基准测试。同样,这取决于您的 InputStream,但 Channel 可能会显示性能优势。
总体而言,我建议使用 ExecutorService 和 Callable class 进行多线程方法的读取和处理内存缓冲区。