windows下使用File I/O遍历目录

Posted

技术标签:

【中文标题】windows下使用File I/O遍历目录【英文标题】:Using File I/O to traverse directory in windows 【发布时间】:2011-12-19 03:52:27 【问题描述】:

我正在编写一个程序,它使用文件 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 之类的东西,它可以工作,但是当我在 Windows 上尝试使用 G:\\Users\\Matt\\Documents 时,它会出错。我输入的打印语句实际上打印出文件夹中的文件,但是程序的其余部分有些混乱:

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

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

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

【问题讨论】:

currentNode 对象在您创建之前在哪里创建 - currentNode.addChild(newNode); 作为全局变量在我的班级顶部的某个地方。 您能否在定义currentNode 时添加该sn-p? FileTraverse.java 中的第 48 行有什么? 我已在 currentNode 行中添加,并在错误所指的行旁边添加了 cmets。 【参考方案1】:

traverse()recursiveTraversal() 的区别有点 对我来说很奇怪;你什么时候使用traverse()?它起什么作用 recursiveTraversal() 还没有做到吗?当然,traverse() 假设 它正在处理一个目录,但 recursiveTraversal() 已经处理 目录很好。

Items 在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();

【讨论】:

是的,这是真的。谢谢你的建议。对不起我的乱码。我刚开始学习数据结构,我会尽快把不必要的东西拿出来。【参考方案2】:

我的猜测是您正在访问一个目录,由于某种原因,Windows 不允许您查看。在这种情况下,listFiles() 很可能返回 null。

【讨论】:

这似乎是可能的,因为该程序似乎适用于其他某些目录.. 还将解释为什么它只是 Windows 上的一个问题。也许尝试以提升的权限再次运行该应用程序。 IE。 “以管理员身份运行”。【参考方案3】:

如果你在第 48 行得到一个NullPointerException,它一定意味着你得到的allFiles 数组是null。根据该方法的JavaDoc,仅当您调用它的文件不是目录或发生某些 IO 错误时才会发生这种情况。这有点奇怪,因为您确实检查了它是否是if 中的目录。也许在操作系统级别上存在一些访问问题,关于权限。

您可能想研究使用 FileFilters 或 java.nio.file 包中的内容。我相信后者使遍历目录更容易。

【讨论】:

【参考方案4】:

来自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 之类的子类,它提供有关调用失败原因的信息。

【讨论】:

【参考方案5】:

我在 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..
     
 

这应该遍历所有用户目录

【讨论】:

以上是关于windows下使用File I/O遍历目录的主要内容,如果未能解决你的问题,请参考以下文章

PHP遍历目录下的图片,按顺序显示问题

PHP遍历并打印指定目录下所有文件实例

lua在linxu和windows系统下的遍历目录的方法

Android如何遍历特定目录下所有文件

java-IO流(File对象-深度遍历指定目录下的文件夹和文件)

python遍历文件