我正在尝试将数据从程序MainProgram传递到我使用反射调用的另一个程序TestProgram。为此,我将Standard.in重新路由到包含要传输的数据的ByteArrayOutputStream。然后,TestProgram使用Standard.inBufferedReaderreadLine()读取。我在一个for循环中多次执行整个操作。问题是这样的:第一次,一切正常,从第二次开始,TestProgramnull读取System.in。 Java文档指出,如果到达流的末尾,则BufferedReader将返回null。但是流中肯定有数据,而我的posByteArrayOutputStream也为0。为什么BufferedReader会突然认为System.in为空或流末?

这是操纵流并调用方法的代码:

for(int i = 0; i < numberOfCases; i++) {

  Byte[] paramBytes = getCurrentParamBytes();

  InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream(paramBytes));

  System.setIn(inputStream);
  String[] params = null;

  testProgram.invoke(null, (Object) params);
}


这是从System.in中读取的代码:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

String current = in.readLine();


我已经使用Eclipse的调试模式向自己保证了System.in的状态,并且一切都很好。从第二次调用null的main方法开始仅读取TestProgram的事实,也令我感到困惑。特别是,由于我检查的所有值都与第一次完全相同(当然,除了流中的数据)。

可悲的是,我不能更改BufferedReader的用法,因为TestProgram不是我的课程,必须按原样使用。

任何帮助将不胜感激。

最佳答案

问题可能是因为BufferedReader在第一次调用时创建了一次。 BufferedReader使用您在循环的第一次迭代中提供的InputStream的实例。在第二次,第三次等调用时,它仍然使用此流,并且不会从更新的System.in中读取。如果您不能修改TestProgram的源代码,我看到2种可能的解决方案。


在每次迭代中创建TestProgram的新实例,而不是重用旧的实例。如果将内部BufferedReader存储为类变量而不是静态变量,则可能有助于“刷新”内部TestProgram
如果您无法创建BufferedReader的新实例,因为它已将状态或InputStream存储在静态变量中,则可以尝试以下操作:使用特殊类型的InputStreams允许您动态连接多个concat。检查ConcatInputStream


第二种方法的示例:

ConcatInputStream concat = new ConcatInputStream();
System.setIn(concat);

for(int i = 0; i < numberOfCases; i++) {

  Byte[] paramBytes = getCurrentParamBytes();

  InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream(paramBytes));

  concat.addInputStream(inputStream);
  String[] params = null;

  testProgram.invoke(null, (Object) params);
}


我不确定它是否会工作,因为我不知道BufferedReader的行为是什么,如果它在第一次调用时看到流的结尾,然后在第二次调用时突然发现流不再为空(因为我们已经向其中添加了新的流TestProgram)。但是希望它会起作用。

还有第三种方法:您可以使用例如反编译BufferedReader JD并找到实例的存储位置。然后您可以使用反射将其设置为零。但这很容易出错。

关于java - BufferedReader返回null,即使它正在读取的流位于pos 0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20332011/

10-12 21:00