使用File I / O遍历windows中的目录

时间:2011-11-01 00:25:06

标签: java windows file io nullpointerexception

我正在编写一个程序,它使用文件I / O遍历用户给出的目录,然后将目录添加到通用链接列表中。我写的程序在Ubuntu上运行得很好,但是当我尝试在Windows上使用它时它不起作用。这是一个相当长的计划,但这是我认为有问题的部分:

private Node<Item> currentNode = new Node<Item>();

public void traverse(File fileObject)
{
    File allFiles[] = fileObject.listFiles();

    for(File aFile: allFiles){
        System.out.println(aFile.getName()); /* debugging */
        recursiveTraversal(aFile); /* Line 34 */
    }
}


public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    if (fileObject.isDirectory()){
        newNode.setData(new Item());

        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){ /* This is line 48 */
            recursiveTraversal(aFile);
        }            

    }else if (fileObject.isFile()){
        newNode.setData(new Item());
    }           
    currentNode = newNode.getParent();
}

当我在Linux上使用它时,我可以给它类似/home/matt/Documents的东西并且它可以工作,但是当我使用G:\\Users\\Matt\\Documents尝试使用Windows时,它会出错。我投入的print语句实际上打印出文件夹中的文件,但是程序其余部分的内容会混乱:

java.lang.NullPointerException
at FileTraverse.recursiveTraversal(FileTraverse.java:48)
at FileTraverse.traverse(FileTraverse.java:34)
at DirectoryMain$ClickAction.actionPerformed(DirectoryMain.java:103)
    ...

之后有很多错误与Swing GUI有关,这个程序正在运行,但我不认为这与任何事情有关。

编辑:添加与跟踪对应的行号。

5 个答案:

答案 0 :(得分:3)

来自File.listFile()的Javadoc(强调补充):

  

返回:一个抽象路径名数组,表示此抽象路径名表示的目录中的文件和目录。如果目录为空,则数组将为空。 如果此抽象路径名不表示目录,或者发生I / O错误,则返回null。

您需要处理来自listFiles()的空回复,遗憾的是,使用java.io.File API无法准确找出发生的错误。

如果您使用的是Java 7,则可以改为使用DirectoryStream类:

private void recursiveTraversal(Path path)
throws IOException
{
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) 
    {
        for (Path entry : stream) 
        {
            //Do something with entry
            doSomething(entry);

            if (Files.isDirectory(entry))
                recursiveTraversal(entry);
        }
    }
}

不同之处在于newDirectoryStream()可以抛出IOException(或AccessDeniedException之类的子类,它提供有关调用失败原因的信息。

答案 1 :(得分:1)

我的猜测是你正在点击一个目录,由于某种原因,windows不允许你查看。 listFiles()很可能在此实例中返回null。

答案 2 :(得分:1)

如果您在第48行获得NullPointerException,则必须表示您获得的allFiles数组为null。根据该方法的JavaDoc,只有在您调用它的文件不是目录或发生某些IO错误时才会出现这种情况。这有点奇怪,因为你检查它是否是if中的目录。可能在操作系统级别存在一些访问问题,涉及权限。

您可能希望了解使用FileFilterjava.nio.file包中的内容。我相信后者使遍历目录变得更容易。

答案 3 :(得分:0)

traverse()recursiveTraversal()之间的差异有点小 对我来说很奇怪;你何时会使用traverse()?它起什么作用 那recursiveTraversal()还没有?当然,traverse()假设 它正在使用目录,但recursiveTraversal()已处理 目录很好。

Item中有recursiveTraversal()的所有小问题,但是 因为他们在这里没有任何东西,所以很难发现实用程序。 :)

public void traverse(File fileObject)
{
    File allFiles[] = fileObject.listFiles();

    for(File aFile: allFiles){
        System.out.println(aFile.getName()); /* debugging */
        recursiveTraversal(aFile);
    }
}


public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    if (fileObject.isDirectory()){
        newNode.setData(new Item());

        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){
            recursiveTraversal(aFile);
        }            

    }else if (fileObject.isFile()){
        newNode.setData(new Item());
    }           
    currentNode = newNode.getParent();
}

我可能会将newNode.setData(new Item()); 移到之上 isDirectory()检查以明确newNode有新的Item 无论当前fileObject是文件还是目录,都会添加到其中:

public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    newNode.setData(new Item());
    if (fileObject.isDirectory()){
        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){
            recursiveTraversal(aFile);
        }            
    }else if (fileObject.isFile()){
        /* must do _something_ with files */
    }           
    currentNode = newNode.getParent();
}

答案 4 :(得分:0)

我在Windows上尝试了类似的东西,程序尝试遍历安全权限限制访问的目录后,程序会崩溃并返回nullPointerException。

除非您需要程序添加安全/隐藏/系统文件夹,否则只需使用try catch子句处理错误。

public static void dive(File file, int level){    
    try{
        for(File x : file.listFiles())
            if(x.isDirectory() && !x.isHidden())
                dive(x);
     }catch(NullPointerException e){
        // Do nothing..
     }
 }

这应该遍历所有用户目录