简体   繁体   English

在Java中如何快速读取不断生成的流的最新字符串?

[英]In Java how to read the latest string of constantly generated stream fast?

In Java I have a process constantly generating output. 在Java中,我有一个不断生成输出的过程。 Of course it's placed into some buffer of the out stream (FiFo) until it's processed. 当然,它会被放到stream (FiFo)的某些缓冲区中,直到处理完毕。 But what I need is sometimes read the latest, actual string of the stream as if it was LiFo. 但是我有时需要读取流的最新实际string ,就好像它是LiFo。 The problem is when I need it, I have to read all the previous output generated between my reads, because streams don't have random access - which is very slow. 问题是当我需要它时,我必须读取两次读取之间生成的所有先前输出,因为流没有随机访问权限-这非常慢。

I use BufferedReader(StreamReader(process.getInputStream())) 我使用BufferedReader(StreamReader(process.getInputStream()))

The buffer of BufferedReader also poses a little problem. BufferedReader的缓冲区也带来了一些问题。 How can I discard all the output I don't need, fast? 如何快速丢弃所有不需要的输出? If possible I wouldn't like to create separate reader-discarder thread. 如果可能的话,我不想创建单独的读写器线程。

I tried: 我试过了:

stdInput = new BufferedReader(new
      InputStreamReader(process.getInputStream()), 1000);

then when I need to read the Output: 然后当我需要阅读输出时:

            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

this way is very slow and takes undetermined time 这种方式非常慢,需要花费不确定的时间

My suggestion (I don't know your implementation): https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int) 我的建议(我不知道您的实现): https : //docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int)

BufferedReader has a mark method: BufferedReader有一个mark方法:

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. 随后对reset()的调用将尝试将流重新定位到这一点。

If you know the size of your data and you can utilize that size to set the position to the part of the stream in which you care about. 如果您知道数据的大小,则可以利用该大小将位置设置为您关心的流部分。

Since you haven't posted the full code, it may be useful for you to try a few things and see what performs best. 由于您尚未发布完整的代码,因此尝试一些操作并查看效果最佳的方法可能对您很有用。 Overall, I'm not sure how much improvement you will see. 总体而言,我不确定您会看到多少改进。

  1. Remove BufferedReader wrapper and benchmark. 删除BufferedReader包装器和基准。 It seems that your InputStream is memory backed. 看来您的InputStream受内存支持。 Hence reads maybe cheap. 因此读起来可能很便宜。 If it is then buffered reader may slow you down. 如果缓冲,则阅读器可能会使您减速。 If reads are expensive, then you should keep it. 如果读取昂贵,那么您应该保留它。

  2. Try Channels.newChannel(InputStream in) and use ReadableByteChannel.read(ByteBUffer dst) and benchmark. 尝试使用Channels.newChannel(InputStream in)并使用ReadableByteChannel.read(ByteBUffer dst)和基准。 Again, it depends on your InputStream, but a Channel may show performance benefits. 同样,它取决于您的InputStream,但是Channel可能会显示性能优势。

Overall I'd recommend going the multithreaded approach with an ExecutorService and Callable class doing the reading and processing into a memory buffer. 总的来说,我建议将ExecutorServiceCallable类用于多线程方法,以将其读取并处理到内存缓冲区中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM