使用File I / O在Windows中遍历目录

我正在编写一个程序,使用文件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上进行尝试时,它将出错。 我input的打印语句实际上打印出文件夹中的文件,但程序的其余部分却弄乱了一些东西:

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

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

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

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

从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这样的子类,它提供了关于调用失败原因的信息。

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

您可能需要考虑使用FileFilterjava.nio.file包中的东西。 我相信后者使遍历目录更容易。

traverse()recursiveTraversal() traverse()之间的区别对我来说有点奇怪, 你什么时候使用traverse() ? 它发挥了什么作用recursiveTraversal()还没有做? 当然, traverse()假定它正在处理一个目录,但是recursiveTraversal()已经很好的处理了目录。

recursiveTraversal()Item的所有操作,但由于在这里什么都不 ,所以很难发现这个工具。 🙂

 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(); } 

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

这应该遍历所有的用户目录