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()
已经处理
目录很好。
Item
s 在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
中的目录。也许在操作系统级别上存在一些访问问题,关于权限。
您可能想研究使用 FileFilter
s 或 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遍历目录的主要内容,如果未能解决你的问题,请参考以下文章