2013-03-05 54 views
0

此问题已被询问once before on Stack Overflow,但堆栈跟踪与我的不同,并且我不认为它是由同一事件引起的。使用Runtime.exec时读取错误

这是我的堆栈跟踪:

java.io.IOException: Read error 
at java.io.FileInputStream.readBytes(Native Method) 
at java.io.FileInputStream.read(Unknown Source) 
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) 
at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
at sun.nio.cs.StreamDecoder.read(Unknown Source) 
at java.io.InputStreamReader.read(Unknown Source) 
at java.io.BufferedReader.fill(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at General.App.cmdString(App.java:393) 
at General.App.cpauString(App.java:422) 
at Functionality.RegistryScanThread.USBDScan(RegistryScanThread.java:109) 
at Functionality.RegistryScanThread.doInBackground(RegistryScanThread.java:51) 
at Functionality.RegistryScanThread.doInBackground(RegistryScanThread.java:1) 
at javax.swing.SwingWorker$1.call(Unknown Source) 
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
at java.util.concurrent.FutureTask.run(Unknown Source) 
at javax.swing.SwingWorker.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

这是比较复杂的程序的简化版本,我写道:

import java.util.*; 
import java.io.*; 
public class Test { 

//global vars 

public Test(){ 
    // initializeing stuffs 
} 
public static void main(String[] args){ 
    ArrayList<String> str = cmdString("reg query hklm"); 
    for(String s : str){ 
     System.out.println(s); 
    } 
} 

public static ArrayList<String> cmdString(String command){ 
    boolean success = false; 
    ArrayList<String> result = new ArrayList<String>(); 
    String line = ""; 
    try{ 
     Process p = Runtime.getRuntime().exec(command); 
     BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
      while ((line = input.readLine()) != null) {result.add(new String(line));} 
     BufferedReader input2 = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
      while ((line = input2.readLine()) != null) {result.add(new String(line));} 
     int exitvalue = p.waitFor(); 
     if (exitvalue != 0){ 
      System.out.println("error!!"); 
      success = false; 

     } 
     else{ 
      success = true; 
     } 
     for(String s : result){ 
      System.out.println(s); 
     } 
     input.close(); 
     input2.close(); 
     return result; 
    } catch(Exception e) { 
     e.printStackTrace(System.err); 
     System.out.println("error!!!"); 
     return result; 
    } 
} 
} 

基本上。在上面的例子中,错误不是真的可见。但在我的程序中,它正在执行所有正确的事情我第一次运行它

然后......当我第二次或第三次运行它时,会发生错误。另外...似乎当我等待一段时间再次运行它时,似乎不会出现任何错误。

我该如何解决这个问题?

+0

你的堆栈跟踪有'FileInputStream',而你的例子没有。我怀疑示例代码触发了相同的错误。 – jdb 2013-03-05 22:05:07

+0

你是对的。说实话,这很奇怪。我在整个程序中都有一个FileInputStream,甚至没有碰过它。只有当我添加了更多的线程时,才开始出现错误。我添加的线程完全不使用这个FileInputStream。我会检查一下,看看我是否可以编辑我的问题。在这一点上,我不确定简单的代码会重现我的错误。 – ThePrince 2013-03-05 22:43:16

回答

0

这就是我认为答案是,我很抱歉,根据我给出的代码来回答我的问题是不可能的。

基本上发生了什么是这个。

  1. 我的程序中的cmdString()方法正在启动一个进程并尝试从其输出流及其错误流中读取。
  2. 恰巧我的程序启动的过程是我设计的一个C++应用程序,它使用自定义管道重定向输入和输出。
  3. 这个C++应用程序有一个用于标准输出的管道,但是我碰巧没有为标准错误创建一个管道。
  4. 因为我没有创建标准错误管道,我的cmdString()方法试图从我没有创建的管道中读取。因此,我得到了与错误流相对应的错误“line = input2.readLine())”。
  5. 所以总之,错误是由于试图从一个没有产生错误流的进程读取一个错误流。

我相信这是发生了什么事。

当我看到触发错误的确切线时,我发现了错误。我能够看到普通的流不会产生错误,但错误流确实如此。我觉得这很奇怪,我立即想起我的C++应用程序没有错误流。

让我知道这个答案是否合理!