Let's say I have a program that asks for three numbers using scanner, something like this:
假设我有一个程序,用扫描器要求三个数字,像这样:
Scanner console = new Scanner(System.in);
int[] numbers = new int[3];
System.out.println("Hello!");
for (int i = 0; i<3; i++){
System.out.print("Please enter a number: ");
numbers[i] = console.nextInt();
}
I want to test a program like this by redirecting some input to it, and then redirecting the output to a file.
我想通过将一些输入重定向到一个程序,然后将输出重定向到一个文件来测试这样的程序。
input.txt
input.txt
3
4
5
command
命令
java program < input.txt > output.txt
The problem is that the output.txt will look something like this
问题是输出。txt会是这样的
Hello!
Please enter a number: Please enter a number: Please enter a number:
As opposed to something like this
而不是像这样
Hello!
Please enter a number: 3
Please enter a number: 4
Please enter a number: 5
Is there any way to make output.txt look more like the second one? I'm on a Mac, if that changes anything.
有什么办法来生产产品吗?txt看起来更像第二个?我在Mac电脑上,如果这改变了什么。
I do NOT want to modify the code - I have to run this test for a lot of similar programs.
我不想修改代码——我必须为许多类似的程序运行这个测试。
3 个解决方案
#1
2
Why your program doesn't work as expected
In your output, the strings "Please enter a number:" are chained without newlines, because you don't print the newlines in the program. When the program is running in interactive mode, the user enters the newlines.
在输出中,字符串“请输入一个数字:”是不带换行的链接,因为您不打印程序中的换行。当程序以交互模式运行时,用户输入换行。
There are no numbers in the output file, because your program doesn't print them to the standard output. Again, when the program is running in interactive mode, the user enters the numbers, but not the program. In the case of redirected output, the numbers coming from the input file are read by the program, but never printed to the standard output.
在输出文件中没有数字,因为您的程序没有将它们打印到标准输出。同样,当程序在交互模式下运行时,用户输入数字,而不是程序。在重定向输出的情况下,来自输入文件的数字由程序读取,但从未打印到标准输出。
The correct way
You should check if the program is running in interactive mode (when the input is read from a TTY).
您应该检查程序是否在交互模式下运行(当从TTY读取输入时)。
test/MyApp.java
测试/ MyApp.java
package test;
import java.util.Scanner;
import java.io.Console;
class MyApp {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
Console console = System.console();
int[] numbers = new int[3];
for (int i = 0; i < 3; i++){
if (console != null) {
System.out.print("Please enter a number: ");
}
numbers[i] = scanner.nextInt();
System.out.printf("Number: %d\n", numbers[i]);
}
}
}
Testing
测试
$ printf '%d\n%d\n%d\n' 1 2 3 > file
$ javac -cp . test/MyApp.java
$ java -cp . test/MyApp < file > out
$ cat out
Number: 1
Number: 2
Number: 3
#2
1
What you may do to have the mixed values for inputs and outputs is :
要使输入和输出的混合值为:
1) Create your own application, which will call the main
method of the application to test (provided all applications have the same package and main class name, or you would have to give this info to your own program, and use reflection to invoke the other program) .
1)创建您自己的应用程序,它将调用应用程序的主方法进行测试(假设所有应用程序都具有相同的包和主类名,或者您必须将此信息提供给您自己的程序,并使用反射调用其他程序)。
Your application will perform the following steps :
您的应用程序将执行以下步骤:
2) Store the regular System InputStream
:
2)存储常规系统InputStream:
InputStream oldInputStream = System.in;
3) Create your own subclass of InputStream (let's call it YourCustomInputStream
), and implement the different read methods, to print what was read from System.in
to System.out
, and also return the value.
3)创建自己的InputStream子类(我们称之为YourCustomInputStream),并实现不同的读取方法,以打印从系统读取的内容。在系统。输出,并返回值。
e.g :
e。旅客:
@Override
public int read(){
int readInt = oldInputStream.read();
System.out.println(readInt);
return readInt;
}
4) Replace the System's input by your own stream :
4)用您自己的流替换系统的输入:
System.setIn(new YourCustomInputStream());
5) Call the main
method of the application to test.
5)调用应用程序的主要方法进行测试。
#3
0
First I wanted to merge stdout and stderr like this:
首先我想把stdout和stderr合并成这样
while read -r num; do
sleep 1
echo ${num}>&2
echo ${num}
done < input.txt | java program
This will fail when you want to redirect the result to a file.
当您希望将结果重定向到文件时,此操作将失败。
So can you try the next construction:
所以你可以试试下一个构造:
while read -r num; do
sleep 1
echo ${num}
done < input.txt| tee -a output.txt| java program >> output.txt
#1
2
Why your program doesn't work as expected
In your output, the strings "Please enter a number:" are chained without newlines, because you don't print the newlines in the program. When the program is running in interactive mode, the user enters the newlines.
在输出中,字符串“请输入一个数字:”是不带换行的链接,因为您不打印程序中的换行。当程序以交互模式运行时,用户输入换行。
There are no numbers in the output file, because your program doesn't print them to the standard output. Again, when the program is running in interactive mode, the user enters the numbers, but not the program. In the case of redirected output, the numbers coming from the input file are read by the program, but never printed to the standard output.
在输出文件中没有数字,因为您的程序没有将它们打印到标准输出。同样,当程序在交互模式下运行时,用户输入数字,而不是程序。在重定向输出的情况下,来自输入文件的数字由程序读取,但从未打印到标准输出。
The correct way
You should check if the program is running in interactive mode (when the input is read from a TTY).
您应该检查程序是否在交互模式下运行(当从TTY读取输入时)。
test/MyApp.java
测试/ MyApp.java
package test;
import java.util.Scanner;
import java.io.Console;
class MyApp {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
Console console = System.console();
int[] numbers = new int[3];
for (int i = 0; i < 3; i++){
if (console != null) {
System.out.print("Please enter a number: ");
}
numbers[i] = scanner.nextInt();
System.out.printf("Number: %d\n", numbers[i]);
}
}
}
Testing
测试
$ printf '%d\n%d\n%d\n' 1 2 3 > file
$ javac -cp . test/MyApp.java
$ java -cp . test/MyApp < file > out
$ cat out
Number: 1
Number: 2
Number: 3
#2
1
What you may do to have the mixed values for inputs and outputs is :
要使输入和输出的混合值为:
1) Create your own application, which will call the main
method of the application to test (provided all applications have the same package and main class name, or you would have to give this info to your own program, and use reflection to invoke the other program) .
1)创建您自己的应用程序,它将调用应用程序的主方法进行测试(假设所有应用程序都具有相同的包和主类名,或者您必须将此信息提供给您自己的程序,并使用反射调用其他程序)。
Your application will perform the following steps :
您的应用程序将执行以下步骤:
2) Store the regular System InputStream
:
2)存储常规系统InputStream:
InputStream oldInputStream = System.in;
3) Create your own subclass of InputStream (let's call it YourCustomInputStream
), and implement the different read methods, to print what was read from System.in
to System.out
, and also return the value.
3)创建自己的InputStream子类(我们称之为YourCustomInputStream),并实现不同的读取方法,以打印从系统读取的内容。在系统。输出,并返回值。
e.g :
e。旅客:
@Override
public int read(){
int readInt = oldInputStream.read();
System.out.println(readInt);
return readInt;
}
4) Replace the System's input by your own stream :
4)用您自己的流替换系统的输入:
System.setIn(new YourCustomInputStream());
5) Call the main
method of the application to test.
5)调用应用程序的主要方法进行测试。
#3
0
First I wanted to merge stdout and stderr like this:
首先我想把stdout和stderr合并成这样
while read -r num; do
sleep 1
echo ${num}>&2
echo ${num}
done < input.txt | java program
This will fail when you want to redirect the result to a file.
当您希望将结果重定向到文件时,此操作将失败。
So can you try the next construction:
所以你可以试试下一个构造:
while read -r num; do
sleep 1
echo ${num}
done < input.txt| tee -a output.txt| java program >> output.txt