管道 java 程序出错

Error in piping java programs

我有一个 class RandomSeq 打印 "args[0]" 随机双打和一个 class Average 打印 StdIn 的平均值。我正在使用 DrJava 编写代码并且 compiling.I 下载了 StdIn 和 out 库并将它们放在我的 classes 的同一文件夹中。我正在学习 Java。

第一个问题在 DrJava 的 "Interactions" 部分。当我写 java RandomSeq 10 > data.txt 而不是创建文本文件时,它会打印输出。为什么?
然后我在 Windows 命令行中输入相同的命令。它成功创建了txt文件。

现在我想将 RandomSeq 10 的输出通过管道传输到 Average 的输入。写作 java RandomSeq 10 | java Average 在 DrJava 的“交互”部分导致了有趣的行为。在 cmd 中写入会打印以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: StdIn
        at Average.main(Average.java:7)
Caused by: java.lang.ClassNotFoundException: StdIn
        at java.net.URLClassLoader.run(Unknown Source)
        at java.net.URLClassLoader.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

甚至 java Average < data.txt 显示相同 error.Why?

public class RandomSeq
{
    public static void main(String[] args)
    {
        int N = Integer.parseInt(args[0]);
        for (int i = 0; i < N; i++)
        {
            System.out.println(Math.random());
        }
    }
}




public class Average
{
    public static void main(String [] args)
    {
        double S = 0;
        int i = 0;
        while (!StdIn.isEmpty())
        {
            double n = StdIn.readDouble();
            S += n;
            i++;
        }
        S = S/i;
        //StdOut.printf("The mean is %.3f", S);
        StdOut.println(S);
    }
}

StdIn 不是来自内置的 Java 库。它是第 3 方库的一部分,包含在可以从 here 下载的 stdlib.jar 文件中。

JAR 文件的路径必须位于命令行 javacjava 调用的 -CLASSPATH 选项中。 this page 使用标准库 部分向您展示了如何执行此操作; -cp 选项只是 shorthand 对应 -CLASSPATH。学习如何将库放入您的 CLASSPATH 非常重要,因为您最终会一直使用 Java.

您的 Average.java 代码还必须 import StdIn class。由于 StdIn 不驻留在命名包中,您只需在代码顶部说 import StdIn;

或者,您可以只使用 System.in,而不是这个库。您可能还需要一个更高级别的流构造。 Here's a nice example.

这是一个related question on StdInStdIn 不是标准的 java 库,正如你提到的你正在学习普林斯顿课程,StdIn.java 是课程提供的,你可能需要编译 StdIn.java同样,使用命令 javac StdIn.java 生成一个 StdIn.class 文件,这将解决 Class not Found Exception。 (第二期)

关于你在 DrJava 中写 java RandomSeq 10 > data.txt 的问题(我要求澄清是因为我没有意识到 DrJava 是一个 IDE,以为它是一本书),是因为Interactions 部分很可能直接将输入提供给您的程序,这意味着它会将您在其中键入的任何内容作为 args[] 传递给您的 main 函数。

打印输出是因为您在代码中调用了 system.out.println,DrJava 只是获取该输出并将其打印到屏幕上,不会通过管道传输到您的 data.txt 文件。我建议您这样做,因为您使用的课​​程 material 需要管道之类的东西才能在命令行中与您的程序进行交互。

最后 java RandomSeq 10 | java Average 与执行 java RandomSeq 10 相同,然后将输出输入 java Average,第二个命令与您执行 java Average < data.txt 相同,错误不是因为你如何管道它,而是因为 StdIn 没有作为编译的 .class 文件存在。