bufferedreader将不会移动到下一行

时间:2013-11-23 19:49:34

标签: java bufferedreader stringtokenizer

晚上好,

我需要从文件中读取一些行,文件是csv,文件结构如下:

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

我需要读取这些值并将它们放入变量中,这就是我尝试这样做的方式:

  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);

第一个int(4)读得很好,但是如果我想移动到下一行它会抛出一个noSuchElementException,所以我不得不在“// why ???”旁边写一行为了移动到下一行,每次我想移动到下一行时,我是否真的必须实例化一个新的标记器?或者有更好的方法吗?

非常感谢

2 个答案:

答案 0 :(得分:4)

让我们看看发生了什么

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

以下内容将解析行"4,"并将其拆分为由,分隔的标记,它将包含1个标记:"4"

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

以下内容会成功,但在执行此操作之前,您确实应该检查st.hasMoreTokens()是否返回true。它将使用"4"中的令牌st,该令牌现在不再包含令牌:

       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???

为什么?

因为st用于解析行"4,"。在解析行之后分配nextline不会更新st的内部状态(这是不可能实现的)。它根本不起作用。因此,如果您在此处致电st.nextToken(),则会按照您说的那样获得NoSuchElementException。因为您已经从"4"阅读了st,并且没有任何令牌。

如果您想使用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.

以下内容现在将从下一行"Mo Farah"返回第一个标记。尽管如此,您确实应首先检查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);

所以简短的回答是,是的,如果你想使用StringTokenizer,你必须为每一行创建一个新的StringTokenizer。如果你不关心行结尾,你可以读取所有行并连接它们,然后将它们全部传递给StringTokenizer

但最简单的方法就是使用String tokens [] = newline.split(“,”);正如马克在答案中所做的那样。

答案 1 :(得分:1)

如果我认为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]);
    }

希望这会有所帮助...