2016-11-11 3 views
0

Ich programmiere Code, der den Speicher meines Computers nach einer bestimmten Datei (oder mehreren gleichen Namens) durchsucht, die durch einen Startpfad angegeben wird. Mein Code scheint für einige Tests gut zu funktionieren, aber als ich dann versuchte, ein allgemeineres Verzeichnis (C: \ Users \ andy) zu verwenden, um nach einer Datei zu suchen, erhalte ich diese Nullzeiger-Ausnahme unten.Null-Zeiger-Ausnahme bei Dateisuche

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) 

Das Programm läuft für ziemlich viel Zeit, während es durch mein C-Laufwerk sucht dann aber nach ein paar Sekunden, die ich geworfen bekommen die obige Ausnahme. Ich bin total verloren und jede Hilfe würde geschätzt werden! (Sorry ich bin hier)

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

48: search(temp); 

32: search(dir); 

33: fileSearch.directorySearch(targetFile, pathToSearch); 

Die Klasse, die den problematischen Code enthält:

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

Der Fehler ist klar: Sie versuchen, auf eine Eigenschaft zugreifen oder rufen Sie eine Methode für ein Null-Objekt bei 'FindFile.java: 44'. Überprüfen Sie diese Zeile und Sie werden sehen, was das Problem ist. – BackSlash

+1

Wenn wir nur wüssten, was in Zeile 44 war ... –

+0

meine Entschuldigung. Dies ist das erste Mal, dass ich stackoverflow benutze, also ertragen Sie mit mir. Ich habe es gerade korrigiert! – bpham93

Antwort

1

In der Zeile

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

die Methode filename.listFiles() kann manchmal Rückkehr null, was zu einer NullPointerException in der for-Schleife führt.

Dies kann z.B. entstehen, wenn dieses Verzeichnis kurz vorher existiert hat, aber dazwischen entfernt wurde. Wenn Sie Ihr C: Laufwerk scannen, kann dies vorkommen, da in der Regel einige Programme im Hintergrund ausgeführt werden, die dies tun können.

+0

ohhh okok das macht jetzt Sinn. also muss ich nur überprüfen, ob diese Methode null ist, bevor ich weitermachen kann, oder? – bpham93

+0

Ja. Weisen Sie filename.listFiles() in einer temporären Variablen zu, prüfen Sie auf Null und führen Sie die for-Schleife nur aus, wenn sie nicht null ist. –

+0

hm okay, ich habe das versucht. Ich habe "if (filename.list(). length> 0)" nach der Überprüfung, ob die Datei ein Verzeichnis ist (erste Zeile der Suchmethode) hinzugefügt, aber ich bekomme immer noch einen Fehler ... Prüfe ich es nicht an der richtigen Stelle? – bpham93

0

Wie @Thomas bemerkt, kann die listFiles()null zurück. Nach dem javadocs kann dies auftreten:

... wenn [die File] bezeichnet kein Verzeichnis oder wenn ein E/A-Fehler auftritt.

Hier sind einige Möglichkeiten:

  1. Es gibt eine Race-Bedingung, wobei das Verzeichnis gelöscht wird, mit einer Datei ersetzt oder aus schreibgeschützt, während das übergeordnete Verzeichnis wiederholt wird.

  2. Das Verzeichnis kann trotz canRead(), das true zurückgibt, nicht aufgeführt werden. Es gibt Szenarien wo dieser Aufruf true zurückgeben kann, aber die Datei oder das Verzeichnis kann nicht gelesen werden.

  3. Es gibt noch eine andere Ursache für die IOException; z.B. ein Netzwerkfehler oder ein Festplatten-IO-Fehler.

Sie sollten nicht davon ausgehen, dass (canRead() && isDirectory()) == true bedeutet, dass Sie nicht ein null bekommen. Test für die null.


1 - Zum Beispiel: http://bugs.java.com/view_bug.do?bug_id=6203387. Ich erinnere mich auch daran, dass etwas seltsames Verhalten passiert ist, wenn ein Syscall von SELinux im "Enforcing" -Modus blockiert wird. Das könnte hier eine Rolle spielen.

+0

danke dafür! Ich habe Probleme, herauszufinden, wie man nach Null sucht, da es ein Dateiobjekt ist ... – bpham93

+0

Weisen Sie es einer temporären Variablen zu und verwenden Sie dann 'tempVar == null'. Es gibt nichts Besonderes an den Dateiobjekten oder dem Ergebnis von 'listFiles()'. –