简体   繁体   English

bufferedreader不会移至下一行

[英]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: 我需要从文件中读取一些行,文件为csv,文件的结构如下:

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???" 第一个int(4)读得很好,但是,如果我想移至下一行,它会引发noSuchElementException,因此我必须在“ // 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" : 下面将分析行"4,"并将其拆分为由分隔的令牌,它将包含1个令牌: "4"

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

The following will succeed but you really should check that st.hasMoreTokens() returns true before doing this. 以下将成功执行,但是您确实应该在执行此操作之前检查st.hasMoreTokens()返回true。 It will consume the token "4" from the st which now contains no more tokens: 它将使用st的令牌"4" ,该令牌现在不再包含令牌:

       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," . 因为使st解析了行"4," Assigning nextline after the line has been parsed does not update the internal state of st (it's impossible to achieve). 在解析该行之后分配nextline不会更新st的内部状态(无法实现)。 It simply doesn't work that way. 这样根本行不通。 So if you call st.nextToken() here, you will get NoSuchElementException as you said. 因此,如果您在此处调用st.nextToken() ,则将获得如您所说的NoSuchElementException Because you already read the "4" from st and there are no tokens left. 因为您已经从st读取了"4" ,所以没有标记了。

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" : 如果您想使用StringTokenizer ,那么以下是正确的做法,它将导致将"Mo Farah,30,"行解析为令牌: "Mo Farah""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" . 现在,以下代码将从下一行"Mo Farah"返回第一个令牌。 Although again, you really should check st.hasMoreTokens() first and give a reasonable error message: 尽管再次,您确实应该首先检查st.hasMoreTokens()并给出合理的错误消息:

       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. 因此,简短的答案是,是的,如果要使用StringTokenizer ,则必须为每行创建一个新的StringTokenizer 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 . 如果您不在乎行尾,则可以先读取所有行并将它们连接起来,然后再将所有行传递给StringTokenizer

But the easiest thing to do is just to use String tokens[] = newline.split(","); 但是最简单的方法就是使用String tokens [] = newline.split(“,”); as Mark did in his answer. 就像马克在回答中所做的那样。

If i suppose the pattern in csv is always the same...: 如果我认为csv中的模式始终相同...:

  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... 希望这可以帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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