2016-11-11 5 views
0

Я программирую код, который ищет хранилище моего компьютера для определенного файла (или нескольких одинаковых имен), обозначенного стартовым путем, все из которых введены в пользовательскую консоль. Мой код, похоже, отлично работает для некоторого тестирования, но затем, когда я попытался использовать более общий каталог (C: \ Users \ andy) для поиска файла, я получаю это исключение нулевого указателя ниже.Исключение Null Pointer во время поиска файла

Exception in thread "main" java.lang.NullPointerException 
    at FindFile.search(FindFile.java:44) 
    at FindFile.search(FindFile.java:48) 
    at FindFile.search(FindFile.java:48) 
    at FindFile.search(FindFile.java:48) 
    at FindFile.directorySearch(FindFile.java:32) 
    at Driver.main(Driver.java:33) 

Программа работает для совсем немного времени, пока он просматривает мой диск С, но затем через несколько секунд я вышвырнут исключение выше. Я полностью потерян, и любая помощь будет оценена! (Жаль, что я новичок в этом)

44: for (File temp : filename.listFiles() 

48: search(temp); 

32: search(dir); 

33: fileSearch.directorySearch(targetFile, pathToSearch); 

Класс, содержащий проблемный код:

public class Driver { 

    public static void main(String[] args) { 

     String targetFile = ""; 
     String pathToSearch = ""; 
     int maxNumber = 0; 

     Scanner input = new Scanner(System.in); 


      System.out.println("max number of files to look for"); 


       maxNumber = input.nextInt(); 

       System.out.println("directory to start in"); 
       pathToSearch = input.next(); 

       System.out.println("What is the file name"); 
       targetFile = input.next(); 

       FindFile fileSearch = new FindFile(maxNumber); 


       try { 

        fileSearch.directorySearch(targetFile, pathToSearch); 

       } catch (IllegalArgumentException e) { 
        System.out.println("you have reach max number of files found"); 

       } 

       int count = fileSearch.getFileResult().size(); 
       if (count == 0) { 
        System.out.println("no results of that file was found"); 
       } else { 
        System.out.println("found " + count + "of file " + targetFile); 
        for (String match : fileSearch.getFileResult()) { 
         System.out.println("location: " + match); 
        } 
       } 



    } 
} 


public class FindFile { 

    private int maxFiles; 
    private List<String> fileResult = new ArrayList<String>(); 
    private String nameOfFile; 
    private int currentNumOfFiles = 0; 

    /* 
    * accepts the max number of files to find 
    */ 
    public FindFile(int maxNum) { 
     maxFiles = maxNum; 

    } 

    public FindFile() { 

    } 

    /* 
    * @param target file name to look for and directory to start search 
    */ 
    public void directorySearch(String target, String directory) { 

     File dir = new File(directory); 
     setNameOfFile(target); 
     if (dir.isDirectory()) { 
      search(dir); 
     } else { 
      System.out.println("not a directory "); 
     } 
    } 

    public void search(File filename) throws IllegalArgumentException { 
     if (filename.isDirectory()) { 
      System.out.println("searching directory..." + filename.getAbsoluteFile()); 
      System.out.println(); 

      if (filename.canRead()) { 
       for (File temp : filename.listFiles()) { 
        if (currentNumOfFiles == maxFiles) { 
         throw new IllegalArgumentException(); 
        } else if (temp.isDirectory()) { 
         search(temp); 

        } else { 

         if (getNameOfFile().equals(temp.getName().toLowerCase())) { 
          fileResult.add(temp.getAbsolutePath().toString()); 
          currentNumOfFiles = getFileResult().size(); 
         } 
        } 

       } 
      } else { 
       System.out.println("cannot read into this directory"); 
      } 
     } 

    } 

    public int getCount() { 
     return currentNumOfFiles; 
    } 

    public int getMaxFiles() { 
     return maxFiles; 
    } 

    public void setMaxFiles(int maxFiles) { 
     this.maxFiles = maxFiles; 
    } 

    public List<String> getFileResult() { 
     return fileResult; 
    } 

    public String getNameOfFile() { 
     return nameOfFile; 
    } 

    public void setNameOfFile(String nameOfFile) { 
     this.nameOfFile = nameOfFile; 
    } 

    public int getCurrentNumOfFiles() { 
     return currentNumOfFiles; 
    } 

    public void setCurrentNumOfFiles(int currentNumOfFiles) { 
     this.currentNumOfFiles = currentNumOfFiles; 
    } 

} 
+0

Ошибка: вы пытаетесь получить доступ к свойству или вызывать метод для нулевого объекта в 'FindFile.java: 44'. Проверьте эту строку, и вы увидите, в чем проблема. – BackSlash

+1

Если бы мы знали, что было в строке 44 ... –

+0

мои извинения. Это мой первый случай использования stackoverflow, так что несите меня. я только что исправил это! – bpham93

ответ

1

В строке

for (File temp : filename.listFiles()) { 

в filename.listFiles метод() может иногда возврат null, что приводит к исключению NullPointerException в for Loop.

Это может быть, например, возникает, если этот каталог существовал незадолго до этого, но был удален между ними. Если вы сканируете свой диск C: это может произойти, так как обычно некоторые программы запускаются в фоновом режиме, что может сделать это.

+0

ohhh okok, что имеет смысл сейчас. поэтому мне просто нужно проверить, не установлен ли этот метод до того, как я смогу двигаться дальше? – bpham93

+0

Да. Назначьте filename.listFiles() во временную переменную, проверьте значение null и сделайте для цикла только, если не null. –

+0

hm okay Я попробовал это. я добавил «if (filename.list(). length> 0)» после проверки, является ли файл каталогом (первая строка метода поиска), но я все еще получаю сообщение об ошибке ... Я не проверяю его в правильном месте? – bpham93

0

Как @Thomas отмечает, listFiles() может вернуть null. Согласно javadocs это может произойти:

... если [File] не обозначает каталог или возникает ошибка ввода-вывода.

Вот некоторые возможности:

  1. Существует состояние гонки в результате чего каталог будет удален, заменен на файл или сделаны только для чтения в то время как родительский каталог итерируемая.

  2. Справочник не может быть указан, несмотря на то, что canRead() возвращается true. Существуют сценарии , где этот вызов может возвращать true, но файл или каталог не могут быть прочитаны в любом случае.

  3. Есть еще одна другая причина для исключения IOException; например сетевой ошибки или ошибки IO жесткого диска.

Вы не должны считать, что (canRead() && isDirectory()) == true означает, что вы не получите null. Тест для null.


1 - Например: http://bugs.java.com/view_bug.do?bug_id=6203387. Я также помню, что некоторые довольно странные действия происходят, когда Syscall блокируется SELinux в режиме принудительного исполнения. Это может иметь отношение здесь.

+0

спасибо за это! у меня возникли проблемы с выяснением того, как проверить null с момента его файла-объекта ... – bpham93

+0

Назначьте его временной переменной, а затем используйте 'tempVar == null'. В объектах File нет ничего особенного или результат 'listFiles()'. –

Смежные вопросы