我正在编写一个程序,它使用文件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有关,这个程序正在运行,但我不认为这与任何事情有关。
编辑:添加与跟踪对应的行号。
答案 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
中的目录。可能在操作系统级别存在一些访问问题,涉及权限。
您可能希望了解使用FileFilter
或java.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..
}
}
这应该遍历所有用户目录