Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read line with Scanner

EDIT for further readers: the problem was that my input file was corrupted.

I don't understand what I'm doing wrong :

I was using this code :

    File f = new File("C:\\Temp\\dico.txt");     BufferedReader r = null;     try {         r = new BufferedReader(new FileReader(f));         String scan;         while((scan=r.readLine())!=null) {             if(scan.length()==0) {continue;}             //treatment         }     } catch (FileNotFoundException ex) {         Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);     } catch (IOException ex) {         Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);     } finally {         if(r!=null) try {             r.close();         } catch (IOException ex) {             Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);         }     } 

Which is working fine. Now, for some reason, I wanted to change for a Scanner. My code became :

    File f = new File("C:\\Temp\\dico.txt");     Scanner r = null;     try {         r = new Scanner(f);         String scan;         while(r.hasNextLine()) {             scan = r.nextLine();             if(scan.length()==0) {continue;}             //treatment         }     } catch (FileNotFoundException ex) {         Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);     } catch (IOException ex) {         Logger.getLogger(Lexique.class.getName()).log(Level.SEVERE, null, ex);     } finally {         if(r!=null) r.close();     } 

This time, we never enter the while, because r.hasNextLine() always returns "false". Any idea about what I'm doing wrong ?

I precise that nothing else changed, the file is still the same.

EDIT : I also precise that I tried with another file and got the same result, meaning it doesn't comes from the file apparently.

The file looks like this :

a à abaissa abaissable abaissables abaissai abaissaient abaissais abaissait ... 

Edit 2 : The content of the file seems to be problematic since the problem persists only if I copy/paste the content from my file to another. In clear, if I write the content myself, it works, if I use a part of the content of my dico.txt file, it doesn't work. Any explanation ?

Edit 3 : These are the links to my files. I advice you to avoid the dico.txt which is very huge.

dico.txt : https://drive.google.com/file/d/0B0sroFy9HZlBNDl3MUwzVnh6VU0/edit?usp=sharing

test.txt : https://drive.google.com/file/d/0B0sroFy9HZlBemZjbXU1RmlmdjQ/edit?usp=sharing

like image 980
Sharcoux Avatar asked Dec 01 '13 10:12

Sharcoux


People also ask

How do you read a line Scanner?

To read the line and move on, we should use the nextLine() method. This method advances the scanner past the current line and returns the input that wasn't reached initially. This method returns the rest of the current line, excluding any line separator at the end of the line.

Can Scanner read a file line by line?

Even though Scanner is more popular as a utility to read user input from the command prompt, you will be glad to know that you can also read a file using Scanner. Similar to BufferedReader, it provides buffering but with a smaller buffer size of 1KB and you can also use the Scanner to read a file line by line in Java.


2 Answers

This code reads the file line by line.

public static void readFileByLine(String fileName) {   try {    File file = new File(fileName);    Scanner scanner = new Scanner(file);    while (scanner.hasNext()) {     System.out.println(scanner.next());    }    scanner.close();   } catch (FileNotFoundException e) {    e.printStackTrace();   }   } 

You can also set a delimiter as a line separator and then perform the same.

 scanner.useDelimiter(System.getProperty("line.separator")); 

You have to check whether there is a next token available and then read the next token. You will also need to doublecheck the input given to the Scanner. i.e. dico.txt. By default, Scanner breaks its input based on whitespace. Please ensure that the input has the delimiters in right place

UPDATED ANSWER for your comment:

I just tried to create an input file with the content as below

a à abaissa abaissable abaissables abaissai abaissaient abaissais abaissait 

tried to read it with the below code.it just worked fine.

 File file = new File("/home/keerthivasan/Desktop/input.txt");      Scanner scr = null;          try {             scr = new Scanner(file);             while(scr.hasNext()){                 System.out.println("line : "+scr.next());             }         } catch (FileNotFoundException ex) {             Logger.getLogger(ScannerTest.class.getName()).log(Level.SEVERE, null, ex);         } 

Output:

line : a line : à line : abaissa line : abaissable line : abaissables line : abaissai line : abaissaient line : abaissais line : abaissait 

so, I am sure that this should work. Since you work in Windows ennvironment, The End of Line (EOL) sequence (0x0D 0x0A, \r\n) is actually two ASCII characters, a combination of the CR and LF characters. if you set your Scanner instance to use delimiter as follows, it will pick up probably

 scr = new Scanner(file);  scr.useDelimiter("\r\n"); 

and then do your looping to read lines. Hope this helps!

like image 80
Keerthivasan Avatar answered Sep 25 '22 12:09

Keerthivasan


next() and nextLine() methods are associated with Scanner and is used for getting String inputs. Their differences are...

next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.

nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.

Read article :Difference between next() and nextLine()

Replace your while loop with :

while(r.hasNext()) {                 scan = r.next();                 System.out.println(scan);                 if(scan.length()==0) {continue;}                 //treatment             } 

Using hasNext() and next() methods will resolve the issue.

like image 37
Nishant Lakhara Avatar answered Sep 24 '22 12:09

Nishant Lakhara