0

I just write a simple commandwrapper in java, this is construction function:

Process process;
Thread in;
Thread out; 

public CommandWrapper(Process process) {
    this.process = process;
    final InputStream inputStream = process.getInputStream();
    // final BufferedReader
    //final BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
    final byte[] buffer = new byte[1024];
    out = new Thread() {
        // String line;
        int lineNumber = 0;

        public void run() {
            try {
                while (true) {
                    int count = inputStream.read(buffer);
                    System.out.println(lineNumber + ":"
                            + new String(buffer, 0, count - 1));
                    // line=r.readLine();
                    // System.out.println(lineNumber+":"+line);
                    lineNumber++;
                }
            } catch (Exception e) {

            }
        }
    };
    final BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));
    final OutputStream outputStream = process.getOutputStream();
    in = new Thread() {
        String line;

        public void run() {
            try {
                //while (true) {
                    outputStream.write((reader.readLine() + "/n")
                            .getBytes());
                    outputStream.flush();
                //}
            } catch (Exception e) {

            }
        }
    };
}

public void startIn() {
    in.start();
}

This is when it invoke:

public static void main(String[] args) {
    try {
        CommandWrapper command = new CommandWrapper(Runtime.getRuntime()
                .exec("wget www.google.com"));
        //command.startIn();
        command.startOut();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

It works OK when I run simple command like ls -l or other local commander, but when I want to run wget command it is print out nothing as output. I do know why.

4

1 回答 1

1

从您展示的代码和您对如何使用它的描述来看,最好的猜测是发生了异常,然后您默默地吞下了它。每当您有一个空catch块时,都会发生这种情况,如下所示:

catch (Exception e) {
}

你碰巧在你的线程run()方法中有一个。out

默默地吞下异常是非常糟糕的做法。

永远不应该这样做!根据您的应用程序,适当的解决方案会有所不同,但由于您正在编写控制台应用程序,因此您可能希望打印异常的堆栈跟踪。在 Java 中,这是通过以下方式完成的e.printStackTrace()

catch (Exception e) {
    e.printStackTrace();
}

另一种选择(在这种特定情况下可能不合适)是重新抛出异常,可能在将其包装在另一个异常中之后(例如,您专门为您的应用程序编写的异常):

catch (Exception e) {
    throw e;
}
// or
catch (Exception e) {
    throw new MyOwnException(e);
}

执行这两个中的任何一个(打印堆栈跟踪或重新抛出)将确保没有异常被忽视。

但是,没有例外的规则;)

在某些情况下,使用空catch子句是合适的。如果您知道某些操作可能会引发异常并且您只想在它发生时继续,那么空catch子句是一个很好的方法。然而,这被挪用的情况仅限于(至少)以下情况:

  1. 您必须知道异常的具体类型。永远不想捕获一般异常(即catch (Exception e),因为您可能无法预测的任何原因可能会引发该异常。如果您使用空catch子句,请始终捕获特定的异常类型(例如IOException

  2. 您必须知道抛出异常的原因。你应该只吞下你知道起源的异常。如果您吞下任何其他异常,您最终会遇到这种情况,您的代码没有按照您的预期执行并且您无法理解原因。被吞下的异常极难调试,因为它们被吞了,因此被隐藏了。

  3. 您必须知道您不关心异常。使用空catch子句的原因主要是(阅读:)处理您正在使用的代码将某些东西视为异常的情况,而您却没有。在这种情况下,我们所说的例外是指“不应该发生的事情,如果发生了,那就是严重错误的事情”。

catch适合使用空子句的示例
: 假设您正在使用其他人的代码打开文件进行读取,给定文件的绝对路径。如果文件不存在,大多数此类例程都会抛出异常 - 这是客户端代码(即调用“打开文件例程”的代码)的工作,以确保文件在尝试打开之前存在。例如,如果运行程序的用户没有读取文件的权限,也会引发异常。

现在,您可能并不真正关心为什么无法打开文件,但如果无法打开,您只想继续 - 在这种情况下,您会吞下所有与读取文件相关的异常(在 Java 中,可能是IOException一些种类)。请注意,您不会吞下所有异常 - 只有与打开文件相关的异常!

于 2012-12-26T03:30:19.860 回答