让我们有一个简单的 Java 应用程序,其中我有以下代码来扫描用户输入:
Scaner scan = new Scanner(System.in);
System.out.print("Enter the value: ");
int value = scan.nextInt();
System.out.println("You entered: " + value);
当我手动运行它时,正如预期的那样,我看到了我输入的内容,示例运行将是:
Enter the value: 3
You entered: 3
但是,当我有一个包含内容的文件时
3
我想通过这个将程序 stdout 重定向到一个文件:
java Test < INPUT > OUTPUT
我得到的全部在 cat OUTPUT
中:
Enter the value: You entered: 3
由于输入的值没有显示在标准输出上,这是正确的,它们不在标准输出上,我知道,我看到它们是因为我手动将它们输入到我的终端。但是,当我像那样重定向标准输出时,我怎样才能让它们也被看到呢?
编辑:
我可以看到代码正在生成 read(0,
系统调用。
$ (strace -ff -e trace=read -e read 2>&1 java Test < INPUT) | grep "read(0,"
[pid 7297] read(0, "3\n", 8192) = 2
有没有更好的拦截方式?
编辑 2:
我的意思是,当我使用 java < INPUT > OUTPUT
运行它时,输出应该如下所示
Enter the value: 3
You entered: 3
最佳答案
您无法修改提供的代码,但可以修改启动方式。
我提供的是假设 System.in 发生变化的 hack。我做了什么:
1) 我使用单个 main
方法和您发布的代码制作了一个测试程序。我启动了它:
$ java -cp dist/Test.jar test.Test <input
Enter the value: You entered: 3
2) 我写了一个 java 程序来做
- 重定向输入流(System.in)
- 启动测试.Test.main
代码:
package redirecter;
import java.io.IOException;
import java.io.InputStream;
public class Redirecter {
public static void main(String[] args) {
final InputStream oldIn = System.in;
InputStream hackedIn = new InputStream() {
@Override
public int read() throws IOException {
int b = oldIn.read();
System.out.write(b);
return b;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int res = oldIn.read(b, off, len);
System.out.write(b, off, res);
return res;
}
};
System.setIn(hackedIn);
test.Test.main(args);
}
}
3) 我用新方法启动旧代码:
$ java -cp dist/Test.jar:../Redirecter/dist/Redirecter.jar redirecter.Redirecter <input
Enter the value: 3
You entered: 3
提供的代码未经编辑;它只是通过棘手的方式推出的。所有参数和 jvm 选项都已保存。如果您有多个入口点,您可以使用反射而不是简单地调用 test.Test.main(args);
坏点:如果有人在提供的代码中编辑 System.in
,黑客就会被破坏。但在使用标准输入之前它似乎是安全的。
关于java - 写入 stdout,也像真正的终端一样打印提供的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20058909/