简体   繁体   English

如何从键盘和文件中读取?

[英]How do I read both from keyboard and from file?

I have a Scanner that could be reading from either keyboard or from a file (via pipes), and apparently there's no way to tell which.我有一个可以从键盘或文件(通过管道)读取的扫描仪,显然无法分辨是哪个。

I have te following code:我有以下代码:

Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
    String line = scan.nextLine();
    doStuff();
}

That works wonderfully when redirecting input to a file.将输入重定向到文件时效果很好。 But if I try to run the program by itself and read from keyboard, it enters an infinite loop.但是如果我尝试自己运行程序并从键盘读取,它就会进入无限循环。 Is there a way to differentiate between reading from keyboard and from a file?有没有办法区分从键盘读取和从文件读取? Thanks in advance!提前致谢!

Edit 1: As requested by @Abra, this is what my code looks like with your suggestion:编辑 1:根据@Abra 的要求,这是我的代码在您的建议下的样子:

Scanner scan = new Scanner(System.in);
do {
    String linea = scan.nextLine();
    doStuff();
} while (System.in.available() != 0 && scan.hasNextLine());

And here's the command I'm running:这是我正在运行的命令:

java -jar Class.jar < File.txt

Edit 2: Solved it, turns out I should only evaluate System.in.available():= 0 once:编辑 2:解决了,原来我应该只评估 System.in.available():= 0 一次:

Scanner scan = new Scanner(System.in);
boolean file = System.in.available() != 0;
do {
    String linea = scan.nextLine();
    doStuff();
} while (file && scan.hasNextLine());

The classic practice used commonly in Linux and Unix is to read input from standard input, as you are already doing. Linux 和 Unix 中常用的经典做法是从标准输入中读取输入,就像你已经在做的那样。 In Java, standard input is called System.in .在 Java 中,标准输入称为System.in

The program reads from standard input and processes what it reads in a loop until it detects end-of-file, which you are already doing.该程序从标准输入中读取并循环处理它读取的内容,直到它检测到文件结尾,您已经在这样做了。

So your program is not stuck - it is merely waiting for more input or for the end-of-file signal to come from the outside.所以你的程序没有卡住——它只是在等待更多的输入或来自外部的文件结束信号。

If you want to use this program with input from a file, you run it like this:如果你想使用来自文件的输入这个程序,你可以像这样运行它:

myprogram < input_file.txt

And if you want your program to get its input from terminal (where you type it), you run it just like如果你想让你的程序从终端(你输入它的地方)获取它的输入,你运行它就像

myprogram

In this case, and after typing your input, you are also responsible to send a special signal from your terminal that will act as a "end-of-file" and will be picked by the program, causing the while -loop to exit.在这种情况下,在键入您的输入后,您还负责从您的终端发送一个特殊信号,该信号将充当“文件结束”并由程序选择,导致while循环退出。 Typically, you do this by pressing Control-D.通常,您可以通过按 Control-D 来执行此操作。

Keep in mind that reading from standard input is not strictly the same as reading from keyboard.请记住,从标准输入读取与从键盘读取并不严格相同。 Standard input only knows about text and end-of-file;标准输入只知道文本和文件结尾; it has no concept of line editing, testing for when shift key is pressed/released etc.它没有行编辑的概念,也没有测试何时按下/释放 shift 键等。

based on the answer of @Abra you can break the loop if System.in is keyboard so:根据@Abra 的回答,如果 System.in 是键盘,您可以打破循环:

import java.util.Scanner;
import java.io.IOException;

public class Main {
    public static void main(String[] argv) throws IOException {
        Scanner scan = new Scanner(System.in);
        boolean isKeyboard = System.in.available() == 0;
        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            doStuff();
            
            if (isKeyboard) {
                break;
            }
        }
    }
}

The class of System.in is java.io.InputStream . System.in的 class 是java.io.InputStream That class has method available() .那个 class 有方法available() If you redirect System.in to a file, as in如果您将System.in重定向到一个文件,如

myprogram < input_file.txt

Then method available() returns a number greater than zero (assuming that input_file.txt has non-zero size) but when System.in refers to the standard input stream, ie when you run your program without redirecting standard input, as in然后方法available()返回一个大于零的数字(假设input_file.txt具有非零大小)但是当System.in引用标准输入 stream 时,即当您运行程序而不重定向标准输入时,如

myprogram

Then method available() returns zero.然后方法available()返回零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM