【问题标题】:Skipping try catch statements?跳过 try catch 语句?
【发布时间】:2016-04-06 20:30:17
【问题描述】:

我正在制作一个刽子手游戏,最近实现了一个文件读取方法来随机化单词;但是,在随机读取文件读取器的哪一行之前,我测试文件阅读器并没有走得太远,而且我的代码似乎跳过了 try catch 块? 以下是使用此方法的构造函数中的一行:

word = determineWord();

方法如下:

String determineWord() {
    String fileName = "HangmanWords.txt";

    String line = null;

    try {
        FileReader fileReader = new FileReader(fileName);

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        while((line = bufferedReader.readLine()) != null) {
            line = bufferedReader.readLine();
        } 

        bufferedReader.close();         
    }
    catch(FileNotFoundException ex) {
        System.out.println("Can't open file");                
    }
    catch(IOException ex) {
        System.out.println("Error reading file");                  
    }
    return line;
}

我收到的错误是 NullPointerException,我相信是因为 line 最初设置为 null,并且 word 在我的程序中不能为 null。

【问题讨论】:

  • 它不会跳过 try-catch 块。但是您在每次迭代时读取两行,并且返回 line 的最终值,该值始终为 null,因为当 line 为 null 时循环停止。不确定您要做什么。
  • @JBNizet while 循环检查并查看是否还有另一行要读取。行应作为文件的最后一行返回。

标签: java


【解决方案1】:

您的 while 循环每次迭代读取 2 行。

while((line = bufferedReader.readLine()) != null) {
    line = bufferedReader.readLine();
} 

不要在循环体中再次 readLine()

String line = null;
while((line = bufferedReader.readLine()) != null) {
            // do something about the line
} 

【讨论】:

  • 我最终将 finalLine = line 放入循环中并返回它。感谢您的回答!
  • 捕获异常根本不是一个好的约定。这实际上是非常糟糕的做法。您应该只捕获您可以并打算处理的异常。
【解决方案2】:

您正在阅读两次,因此在文件末尾将 null 分配给您要返回的行。您可以在阅读前进行检查或只阅读一次。

while(bufferedReader.readLine().hasNext()) {
   line = bufferedReader.readLine();
}

【讨论】:

    【解决方案3】:

    您的代码是错误的:它在每次迭代时读取两行而不是仅一行,并且它返回 line,它始终为 null,因为这是循环停止的条件。代码应该是这样的

    String lastReadLine = null;
    while((line = bufferedReader.readLine()) != null) {
        lastReadLine = line;
    }
    return lastReadLine; 
    

    当出现错误时,我也会避免返回 null 或一些随机行。如果有异常,你不应该继续,好像什么都没发生一样。扔掉它而不是抓住它。

    无论发生什么,您都应该确保阅读器已关闭。这就是 try-with-resources 语句的用途:

    String determineWord() throws IOException {
        String fileName = "HangmanWords.txt";
    
        try (FileReader fileReader = new FileReader(fileName);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {
    
            String line = null;
            String lastReadLine = null;
            while((line = bufferedReader.readLine()) != null) {
                lastReadLine = line;
            }
            return lastReadLine; 
        }
    }
    

    【讨论】:

      【解决方案4】:

      您的while 循环不正确。它的后置条件是line == null,也就是你的程序每次离开line的状态。

      您应该创建一个单独的变量,并将其设置为文件中的某个随机line

      这里有一个简单的方法,不统一:

      private Random rnd = new Random();
      
      String determineWord() {
          String fileName = "HangmanWords.txt";
      
          String res = null;
      
          try {
              FileReader fileReader = new FileReader(fileName);
              BufferedReader bufferedReader = new BufferedReader(fileReader);
              String line = null;
              int count = 1;
              while((line = bufferedReader.readLine()) != null) {
                  if (res == null || 4*rnd.nextInt(count) > count) {
                      res = line;
                  }
                  count++;
              } 
      
              bufferedReader.close();         
          }
          catch(FileNotFoundException ex) {
              System.out.println("Can't open file");                
          }
          catch(IOException ex) {
              System.out.println("Error reading file");                  
          }
          return res;
      }
      

      令人惊讶的是,这个过程有些棘手,除非您事先知道文本文件中有多少行。有关如何以统一方式执行此操作的信息,请参阅 reservoir sampling algorithm

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-11
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-17
        • 1970-01-01
        相关资源
        最近更新 更多