【问题标题】:`NullPointerException` thrown while searching text file [closed]搜索文本文件时抛出`NullPointerException`[关闭]
【发布时间】:2015-06-02 04:58:53
【问题描述】:

首先,我在下面 ** 的行中不断收到 NullPointerException。 其次,我的程序给出了错误的输出(我以某种方式让它工作,但后来又回到错误)。一定是逻辑错误。我有一个 11 行的文件 directory.txt,每行都有一个名称。当我运行我的程序以尝试查找某个名称时,它只在第一行找到第一个名称,而其他所有内容都找不到。如何修复这 2 个错误?

我有 2 节课。这是一级目录:

import java.util.*;
import java.io.*;
public class Directory {
   //public static void main(String[] args) {
   final int maxDirectorySize = 1024;
   String directory[] = new String[maxDirectorySize];
   int directorySize = 0;
   File directoryFile = null;
   Scanner directoryDataIn = null;

   public Directory(String directoryFileName) {
      directoryFile = new File(directoryFileName);
      try {
         directoryDataIn = new Scanner(directoryFile);
      }
      catch (FileNotFoundException e) {
         System.out.println("File is not found, exiting!" + directoryFileName);
         System.exit(0);
      }
      while (directoryDataIn.hasNext()) {
         directory[directorySize++] = directoryDataIn.nextLine();
      }
   }
   public boolean inDirectory(String name) {
      boolean inDir = true;
      for (int i = 0; i < directory.length; i++) {
         **if (directory[i].equalsIgnoreCase(name))** 
            inDir = true;
         else 
            inDir = false;
      }
      return inDir;
   }
   public boolean add(String name) {
      if (directory.length == 1024)
         return false;
      for (int i = 0; i < directory.length; i++) {
         if (directory[i].equalsIgnoreCase(name))
            return false;
         else
            directory[directorySize++] = name;
            return true;
      }
      return false;
   }          

   public boolean delete(String name) {
      for (int i = 0; i < directory.length; i++) {
         if (directory[i].equalsIgnoreCase(name)) {
            directory[i] = null;
            return true;
         }   
         else
            return false;
      }
      return false;
   }

   public void closeDirectory() {
      directoryDataIn.close();
      PrintStream directoryDataOut = null;
      try {
          directoryDataOut = new PrintStream(directoryFile);
      }
      catch (FileNotFoundException e) {
         System.out.printf("File %s not found, exiting!", directoryFile);
         System.exit(0);
      }
      String originalDirectory[] = {"Mike","Jim","Barry","Cristian","Vincent","Chengjun","susan","ng","serena"};
      if (originalDirectory == directory)
         System.exit(0);
      else
         for (int i = 0; i < directorySize; i++)
            directoryDataOut.println(directory[i]);
         directoryDataOut.close();
   }
}

这是我尝试运行的第二个课程,但我不断收到异常主线程 NullPointerException。

import java.io.*;
import java.util.*;
public class DirectoryWithObjectDesign {
   public static void main(String[] args) throws IOException {
   String directoryDataFile  = "Directory.txt";
   Directory d = new Directory(directoryDataFile);
   Scanner stdin = new Scanner(System.in);
   System.out.println("Directory Server is Ready!");
   System.out.println("Format: command name");
   System.out.println("Enter ^Z to end");
   while (stdin.hasNext()) {
      String command = stdin.next();
      String name = stdin.next();
      if (command.equalsIgnoreCase("find")) {
         if (d.inDirectory(name))
            System.out.println(name + " is in the directory");
         else 
            System.out.println(name + " is NOT in the directory");
      }
      else if (command.equalsIgnoreCase("add")) {
         if (d.add(name))
            System.out.println(name + " added");
         else 
            System.out.println(name + " cannot add! " + "no more space or already in directory");
      }
      else if (command.equalsIgnoreCase("delete")) {
         if (d.delete(name))
            System.out.println(name + " deleted");
         else
            System.out.println(name + " NOT in directory");
      }
      else {
         System.out.println("bad command, try again");
      }
   }
   }
}   

【问题讨论】:

  • 你试过调试你的程序吗?异常堆栈跟踪在哪里?
  • 检查抛出 NullPointerException 的行号。

标签: java java.util.scanner


【解决方案1】:

改变

for (int i = 0; i < directory.length; i++) {

for (int i = 0; i < directorySize; i++ ){

directorySize 已经在跟踪条目的数量,因此任何高于该数量的数组条目都将为空。因此,尝试对它们调用 equalsIgnoreCase() 将获得 NPE。

实际上,这看起来像是 ArrayList 而不是数组的主要用途。该列表将根据您的需要扩展,List.size() 将为您提供正确的长度。

【讨论】:

  • 这有什么问题?
  • 你试过编译吗?
  • 不,这只是一个代码 sn-p 来指出我认为问题出在哪里。对于我正在尝试提供帮助并在平板电脑上打字的 (),我深表歉意。我得到的只是“虐待”。我是这个回答问题的新手。如果我有足够的声誉,我可能会发表评论,但如果我的答案被如此糟糕地否决,我将永远得不到任何答案。如果您如此严厉地对待新手,这似乎是确保社区停滞不前的好方法。
  • 不回答你,有什么问题,我问你:这个回答有什么帮助?您建议使用全新的方法directorySize,而无需解释它应该做什么。然后你建议使用ArrayList 而不是数组,但没有解释如何做到这一点。由于您在使用List API 时遇到问题(因为您显然是指directory.size()),很明显,您还没有考虑到这一点。我建议删除该答案,解决问题并提供有关如何使用列表而不是数组的示例。然后你可以取消删除它。
  • 不,() 不应该在那里抱歉。我的意思是字段 directorySize 已经在跟踪已添加的条目数。对 ArrayList 的引用是一个替代建议,我承认我没有完全解释。但我的意思是在这种情况下用列表替换数组。我原以为如果不理解,就会添加评论,而不仅仅是无缘无故地投反对票。
【解决方案2】:

这段代码:

  while (directoryDataIn.hasNext()) {
     directory[directorySize++] = directoryDataIn.nextLine();
  }

只会填充与输入文件中的行一样多的directory(根据您的问题为 11 行)。

这段代码:

  for (int i = 0; i < directory.length; i++) {
     **if (directory[i].equalsIgnoreCase(name))** 

将遍历directory 中的每个条目,直至其长度 (1024)。

由于这些条目中有 1013 个是 null,因此尝试在它们上运行 equalsIgnoreCase() 将导致 NPE。

编辑

您可以通过以下几种方法之一来解决此问题。例如,你可以

  • 跟踪您阅读的行数,并且只阅读到该点
  • 在评估之前检查每个条目是否为null
  • 使用动态大小的数据结构而不是数组,例如ArrayList
  • 检查已知值(例如if (name.equalsIgnoreCase(directory[i]))

【讨论】:

  • 我有点明白你想说什么......但我该如何解决这个问题?我需要 equalsIgnoreCase 来查看目录中是否有名称... @azurefrog
  • 我摆脱了 NPE 错误,但仍然出现逻辑错误......所以即使名称在文本文件中,它也会不断返回名称不在目录中。知道为什么吗?
  • 这真的很奇怪。有时我会收到 NPE 错误,有时我不会。不知道如何解决它或为什么它有时会出现..
  • 即使在中途找到匹配项,您也会遍历整个数组。如果您在找到匹配项后不停止,那么您检查的下一件事可能不会,因此会将 inDir 更改回 false。找到所需内容后,您需要breakreturn
  • 关于间歇性 NPE,没有看到您现在使用的代码,我无法猜测原因。如果您编辑原始问题以添加有关更新代码的后续内容,我会尽力为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多