简体   繁体   中英

Simple issue about possible to re use java Scanner?

I am still new to java and is it possible to re use the Scanner object? The below example is I am reading a file to do characters, words and lines count. I know there must be a better way to do counting with one scanner object only but that is not the main point. I just wonder why there is input.close() but no input.open() or input.reset etc.. Since I am actually reading the same file, is it possible to create only one Scanner object and pass for 3 methods to use? Thanks

public class Test {

    /**
     * @throws java.io.FileNotFoundException
     */
    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("demo.java");
        Scanner input = new Scanner(file);
        Scanner input2 = new Scanner(file);
        Scanner input3 = new Scanner(file);
        int lines = 0;
        int words = 0;
        int characters = 0;

        checkCharacters(input3);
        checkLines(input);
        checkwords(input2);

    }

    private static void checkLines(Scanner input) {
        int count = 0;
        while (input.hasNext()) {

            String temp = input.nextLine();
            String result = temp;
            count++;
        }
        System.out.printf("%d lines \n", count);
    }

    private static void checkwords(Scanner input2) {
        int count = 0;
        while (input2.hasNext()) {
            String temp = input2.next();
            String result = temp;
            count++;
        }
        System.out.printf("%d words \n", count);
    }

    private static void checkCharacters(Scanner input3) {
        int count = 0;
        while (input3.hasNext()) {
            String temp = input3.nextLine();
            String result = temp;
            count += temp.length();
        }
        System.out.printf("%d characters \n", count);
    }
}

No, there's no way to reset the Scanner from a method on the Scanner. You might be able to do it if you passed in an InputStream into the scanner and then reset the stream directly but I don't think it's worth it.

You seem to be parsing the same file 3 times and processing the same input 3 times. That seems like a waste of processing. Couldn't you perform all 3 counts at once?

private static int[] getCounts(Scanner input) {

   int[] counts = new int[3];

   while(input.hasNextLine()){
      String line = input.nextLine();
      counts[0]++; // lines

      counts[2]+=line.length(); //chars

      //count words
      //for simplicity make a new scanner could probably be better
      //using regex or StringTokenizer
      try(Scanner wordScanner = new Scanner(line)){
           while (wordScanner.hasNext()) {
               wordScanner.next();
               count[1] ++;  //words
           }
      }
   }

   return counts;

}

Of course the Object Oriented way would be to return a new object named something like Counts with methods to getNumLines() , getNumChars() etc.

EDIT

One thing to note, I kept the calculations the same as you had in the original question. I'm not sure if the counts will always be accurate especially characters since Scanner may not return all end of line characters so the chars count may be off and the number of lines may be off if there are consecutive blank lines? You would need to test this.

No it is not possible because as the documentation says

void close()
           throws IOException

Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.

Once a resource is relaesed there is no way to get it back, untill you have a reference to it , which is actually closed

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