简体   繁体   中英

How to “reset” or “clear” System.in using java application?

I was running a java application roughly like the one below:

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
while (true) {
    try {
        String inputStr = null;
        if ((inputStr=bufReader.readLine()) != null) {
            //DO SOMETHING
        }
        else {
            System.out.println("input is null");
        }
    }
    catch (Exception e) {
        //DO SOMETHING
    }
}

using this command java test < textfilename but after all the things are read in, the application starts to keep printing input is null . Of course I can add break; below System.out.println("input is null"); , but does there exist a way that can clears the input buffer and starts to get input from command line?

PS: An example of a file I am using:

11111111
11111112
11111113
11111114

As far as I know it's not possible. When you use < in the command line to read from a file, the content of System.in is controlled by the shell, not by Java.

readLine() returning null is the way Java signals that you've reached the end of file, and is also what you get if you send EOF /type Ctrl-D in the shell.

You can't redirect input or output and have access to the normal console System.in . From the docs (emphasis mine):

Whether a virtual machine has a console is dependent upon the underlying platform and also upon the manner in which the virtual machine is invoked. If the virtual machine is started from an interactive command line without redirecting the standard input and output streams then its console will exist and will typically be connected to the keyboard and display from which the virtual machine was launched.

That said, you can still largely accomplish what you want with minimal changes to your code.

public static void main(String args[]) throws FileNotFoundException {
    readFile(args[0]);
    // Continue normal console input here
}

private static void readFile(String filename) throws FileNotFoundException {
    InputStream original = System.in;
    System.setIn(new FileInputStream(filename)); // VM trickery

    try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in))) { 
        String inputStr = null;
        while ((inputStr = bufReader.readLine()) != null) { // stops loop on `null`
            System.out.println(inputStr);
        }
    } catch (IOException e) { 
        e.printStackTrace();
    }

    System.setIn(original); // more VM trickery
}

Key changes:

  • Is invoked with the filename of the input file as the first argument, ie java test textfilename
  • Uses FileInputStream
  • Using try-with-resources to ensure the FileInputStream I added is closed
  • Handles the null return of readLine() to not infinitely loop on null

Maybe something like this:

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
String inputStr = null;
try {
   while ((inputStr=bufReader.readLine()) != null) {
   //DO SOMETHING
   }
}catch (Exception e) {
//DO SOMETHING
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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