代码之家  ›  专栏  ›  技术社区  ›  ThePrince

使用Runtime.exec时读取错误

  •  0
  • ThePrince  · 技术社区  · 13 年前

    有人问过这个问题 once before on Stack Overflow ,但堆栈跟踪与我的不同,我不认为这是由同一件事引起的。

    这是我的堆栈跟踪:

    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;
        }
    }
    }
    

    大体上在上面的例子中,错误并不是真正可见的。但在我的程序中,它正确地执行了所有内容 我第一次运行它 .

    然后当我第二次或第三次运行它时,会出现错误。而且当我等待一段时间再运行它时,似乎没有出现任何错误。

    我该如何解决这个问题?

    1 回复  |  直到 9 年前
        1
  •  0
  •   ThePrince    13 年前

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

    基本上就是这样。

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

    我相信事情就是这样。

    当我看到触发错误的确切行时,我发现了这个错误。我能够看到正常的流没有产生错误,但错误流产生了。我觉得这很奇怪,我立刻想起我的C++应用程序没有错误流。

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