简体   繁体   中英

bufferedreader won't move to the next line

Good evening,

I need to read some lines from a file, the file is csv and the file is structured like so:

4,
Mo Farah,30,
Jessica Ennis,27,

i need to read those values and put them into variables, that's how i tried to do this:

  while(nextline != null){
           StringTokenizer st = new StringTokenizer(nextline,",");
           int size = Integer.parseInt(st.nextToken());
           System.out.println(size);

           nextline = reader.readLine();

           StringTokenizer st2 = new StringTokenizer(nextline, ","); //why???


           String name = st2.nextToken();
           System.out.println(name);
           int age = Integer.parseInt(st2.nextToken());

           System.out.println(age);

the first int (4) is read just fine, however if i want to move to the next line it throws a noSuchElementException, so i had to write the line next to "//why???" in order to move to the next line, do i really have to instantiate a new tokenizer each time i want to move to the next line? or is there a better way of doing this?

Thank you very much

Lets have a look at what goes on

nextline = reader.readLine(); // I'm assuming you have this here
while(nextline != null){

The following will parse the line "4," and split it into tokens separated by , it will contain 1 token: "4" :

       StringTokenizer st = new StringTokenizer(nextline,",");

The following will succeed but you really should check that st.hasMoreTokens() returns true before doing this. It will consume the token "4" from the st which now contains no more tokens:

       int size = Integer.parseInt(st.nextToken());
       System.out.println(size);

       // We read the next line into "nextline", this is okay but not pretty.
       // Also you need to check that nextline is not `null` here.
       nextline = reader.readLine();

       StringTokenizer st2 = new StringTokenizer(nextline, ","); //why???

Why?

Because st was made to parse the line "4," . Assigning nextline after the line has been parsed does not update the internal state of st (it's impossible to achieve). It simply doesn't work that way. So if you call st.nextToken() here, you will get NoSuchElementException as you said. Because you already read the "4" from st and there are no tokens left.

The following is the right thing to do if you want to use StringTokenizer , it will cause the line "Mo Farah,30," to be parsed to tokens: "Mo Farah" and "30" :

       st = new StringTokenizer(nextline, ","); // Just parse the new line.
       // You can reuse the old st variable as it is now depleted.

The following will now return the first token from the next line which is "Mo Farah" . Although again, you really should check st.hasMoreTokens() first and give a reasonable error message:

       String name = st.nextToken(); // Change from st2 to st
       System.out.println(name);
       int age = Integer.parseInt(st.nextToken()); // Ditto

       System.out.println(age);

So the short answer is, yes, if you want to use StringTokenizer you have to make a new StringTokenizer for every line. If you don't care above line endings you can just read all lines and concatenate them before passing all of it to the StringTokenizer .

But the easiest thing to do is just to use String tokens[] = newline.split(","); as Mark did in his answer.

If i suppose the pattern in csv is always the same...:

  while(nextline != null){ 

      String[] lecture = reader.readLine().split(",");

       if(lecture.lenght()>0){
                  System.out.println("Name: " + lecture[0]);
               int age = Integer.parseInt(lecture[1]);//you need to int?

                  System.out.println(lecture[1]);
        }
              else
                  System.out.println("Name: " + lecture[0]);
    }

hope this helps...

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