-2

What is the problem with Scanner hasNext() method? When hasNext() method read empty txt file and get false, after i write something to file and recheck with hasNext() but this time it again returns false. But when i remove if(hasNext()) block it works fine. I suspect that problem occurs due to s.hasNext() method. Is there bug in Scanner class?

public static void main(String[] args) throws Exception {
File file= new File("file.txt");

FileWriter fw = new FileWriter(file, true);
PrintWriter pw = new PrintWriter(fw);

FileReader fr = new FileReader(file);
Scanner s = new Scanner(fr);

if (s.hasNext()) {  // RETURNS FALSE GOES TO ELSE OK(because file is empty)
      //doSomething();
} else{
    pw.println(1);  // WRITE SOMETHING TO FILE
    pw.close();
    System.out.println(s.hasNext());  // returns FALSE AGAIN
    int num = s.nextInt();
    System.out.println("LOOP: " + num + " ***");
    s.close();
}

}

Safar Safarli
  • 81
  • 2
  • 8
  • In the first case you're writing to file and in the second case you're writing to counterfile. And creating a FileWriter deletes the previous contents of the file. So then the file is empty. – user253751 Mar 19 '18 at 23:25
  • My problem isn't that. The first if(s.hasNext()) returns false, thus its block not executed, because my txt file is empty. But why second else block gives error?! – Safar Safarli Mar 19 '18 at 23:28
  • I want this: if file is empty then go else block and write 1 to text file, then whenever i run this code i want it check the previous value and + 1 – Safar Safarli Mar 19 '18 at 23:31
  • I think there is bug in the Scanner class – Safar Safarli Mar 19 '18 at 23:32
  • the "if(s.hasNext())" block even won't executed(returns false). Why else block fails at "int num = s.nextInt();" statement – Safar Safarli Mar 19 '18 at 23:40
  • Probably you're causing weird things to happen by reading and writing the same file at the same time. Don't do that. – user253751 Mar 19 '18 at 23:51
  • first, txt file is empty so "if(hasNext())" gets false and won't execute its block, but when execution flow goes to else statement, problem occurs. hasNext() does something weird?? – Safar Safarli Mar 20 '18 at 00:02
  • In other words. When "else block" execute after "if" gets false, it doesn't work. But when i remove "if block" and run only "else block" content it works. Problem is "hasNext()" method – Safar Safarli Mar 20 '18 at 00:05
  • 1
    `Scanner` seems to be assuming that if the file is empty, it stays empty. Hence, don't try to read and write the same file at the same time. – user253751 Mar 20 '18 at 01:06
  • Please post the contents of your file and the stacktrace of the exception, otherwise people can only guess what's going on. – Max Vollmer Mar 20 '18 at 05:06
  • And please tell us on which line the exception is thrown, because the line nubers in The stack the stacktrace won't help us. – sn42 Mar 20 '18 at 06:20
  • Possible duplicate of [How do filesystems handle concurrent read/write?](https://stackoverflow.com/questions/2751734/how-do-filesystems-handle-concurrent-read-write) – sn42 Mar 20 '18 at 06:38

1 Answers1

1

If you want to check what happens with your scanner object you can try to check value of .hasNext() in your else block. I suppose it should be false (as it is when you check it in your if statement).

It looks like you have to create a new Scanner in else statement because the first one does not catch changes in the file. As far as I understand it's not a bug but API decision.

Following example can confirm my understanding:

public class ScannerTest {

  public static void main(final String[] args) throws IOException {
    final File file = new File("testFile.txt");
    file.delete();

    final PrintWriter printWriter = new PrintWriter(new FileWriter(file, true));

    final Scanner scanner = new Scanner(file);

    System.out.println(scanner.hasNext()); // prints false because the file is empty
    printWriter.write("new line");
    printWriter.close();
    System.out.println(scanner.hasNext()); // prints false because the file is still empty for the first scanner

    // We instantiate a new Scanner
    final Scanner scannerTwo = new Scanner(file);
    System.out.println(scannerTwo.hasNext()); // prints true
  }
}

If we take a look into javadoc for respective Scanner constructor we can find out that:

Constructs a new Scanner that produces values scanned from the specified file.

As I interpret it, the file is scanned under instantiating of Scanner and changes of the file could not be caught by the scanner instance later. That's why it's necessary to create a new instance of Scanner to read updated file.

contrapost
  • 673
  • 12
  • 22
  • There's no point checking it in else block. I'm checking it in "if" statement – Safar Safarli Mar 20 '18 at 01:17
  • You mention that "changes of the file could not be caught by the scanner instance later." But this works fine, https://codeshare.io/21bXJz PROBLEM is hasNext method(), other write/read works fine – Safar Safarli Mar 20 '18 at 10:29
  • It looks like you reading from a file that isn't empty at the beginning. If your file is empty when you start executing of your program you should get NoSuchElementException. In my example replacing System.out.println(scanner.hasNext()); with System.out.println(scanner.next()); results (as it is expected) in NoSuchElementException. – contrapost Mar 20 '18 at 10:46
  • In the beginning my txt file empty it is right. then i write into it with println(); then i read it. After i write it some data(with code), txt file isn't empty then. – Safar Safarli Mar 20 '18 at 10:58
  • Problem is hasNext() method, once you call it and get false, other hasNext() and nextInt() nextLine() won't work anymore! after that. – Safar Safarli Mar 20 '18 at 11:02
  • That's not true. You can call hasNext() as many time as you want. If you file is empty it will always return false. But if you call next(), nextInt(), nextLine() after you get false from hasNext() you will get NoSuchElementException and you program will crash. – contrapost Mar 20 '18 at 11:07
  • Problem is that. What causes that, i called hasNext() when file is empty, OK, but then write to that file, and called hasNext() again, BUT returns false again. – Safar Safarli Mar 20 '18 at 11:20
  • WHY, this happens, i want to be clarified – Safar Safarli Mar 20 '18 at 11:21
  • @SafarSafarli I've never seen such abuse of comments. You may want to try and keep the amount of comments down. It seems you are more trying to be right than to learn; in that case, don't ask the question in the first place. – Maarten Bodewes Nov 14 '19 at 16:52