2

对于我正在做的一个项目,我制作了一个 java 程序来搜索用户输入指定的文件。

代码开始在用户指定的基本目录中搜索(即:C:)。它遍历此目录中的所有文件,检查文件名是否与用户给出的搜索词匹配,如果匹配,则将文件绝对路径添加到字符串中。如果文件是目录,则将其添加到稍后处理的列表中。

搜索完基本文件夹后,它将以相同的方式搜索/删除列表中的第一个目录(再次将找到的任何目录添加到列表中)并继续直到没有更多目录可供搜索。然后向用户显示找到的文件。

我的问题; 有没有更好的方法来搜索文件?也许立即搜索目录而不是将它们添加到列表中?任何建议都会很棒,在此先感谢!这是我的代码。

public String SearchDir(File directory){
    this.directory = directory;
    do{
        File[] files = this.directory.listFiles();
        if(files != null){
            for(int i = 0; i < files.length; i++){

                // The current file.
                File currentFile = files[i];

                // The files name without extension and path
                // ie C:\Documents and Settings\myfile.file = myfile
                String fileName = this    .removeExtension(this.removePath(currentFile.getName()));


                // Don't search hidden files
                if(currentFile.isHidden()){
                    continue;
                }
                System.out.println(currentFile.getAbsolutePath());

                // Check if the user wanted a narrow search
                if(this.narrow){
                    // Narrow search = check if the file STARTS with the     string given.
                        if(fileName.toLowerCase().startsWith(this.fileName.toLowerCase())){
                    this.found += currentFile.getAbsolutePath() + '\n';
                    this.foundXTimes++;
                }
            }
            else{
                // Non-Narrow search = check for the given string ANYWHERE in the file name.
                if(fileName.toLowerCase().contains(this.fileName.toLowerCase())){
                    this.found += currentFile.getAbsolutePath() + '\n';
                    this.foundXTimes++;
                }
            }

                // If the file is a directory add it to the buffer to be     searched later.
                if(currentFile.isDirectory()){
                    this.directoriesToSearch.add(currentFile);
                }
            }

            if(!this.directoriesToSearch.isEmpty()){
                this.directory = this.directoriesToSearch.remove(0);    
            }
        }
    } while(!this.directoriesToSearch.isEmpty());

    if(!this.found.equals(""))
        return this.found;
    else
        return "x";
}
4

2 回答 2

6

There are two algorithms. Depth first search and breadth first search.
http://en.wikipedia.org/wiki/Depth-first_search
http://en.wikipedia.org/wiki/Breadth-first_search

These algorithms time efficiency is O(n) for your question. Better is imposible. But you can build binary tree. Then your search's efficiency is O(logn). But firstly, you have to allow time for binary tree building. If you search only one, dont use binary tree.

于 2013-05-27T15:14:50.637 回答
5

walkFileTree()JDK7 中有一个可以扩展的方法。

引用Java 教程

要遍历文件树,您首先需要实现一个FileVisitor. A FileVisitor指定遍历过程中关键点所需的行为:访问文件时、访问目录之前、访问目录之后或发生故障时。该接口有四种方法对应这些情况:

  • preVisitDirectory. 在访问目录的条目之前调用。* postVisitDirectory. 在访问目录中的所有条目后调用。如果遇到任何错误,则将特定异常传递给该方法。* visitFile. 在被访问的文件上调用。文件BasicFileAttributes被传递给方法,或者您可以使用文件属性包来读取一组特定的属性。例如,您可以选择读取文件 DosFileAttributeView以确定文件是否设置了“隐藏”位。*`访问文件失败。无法访问文件时调用。将特定异常传递给该方法。您可以选择是否抛出异常,将其打印到控制台或日志文件等。

如果您不需要实现所有四个FileVisitor方法,而不是实现FileVisitor接口,您可以扩展SimpleFileVisitor类。这个实现 FileVisitor接口的类访问树中的所有文件并在 IOError遇到错误时抛出一个。您可以扩展此类并仅覆盖您需要的方法。

以下代码不是我的,它来自这里,但它是如何遍历路径中所有文件的一个清晰示例:

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

/** Lists all files in the given directory recursively.
 * .svn directories are ignored.
 */
public class Find extends SimpleFileVisitor<Path> {

 /** Main program.
  * @param args Command line arguments - directories to search.
  */
 public static void main(final String... args) throws IOException {
     final FileVisitor<Path> fileVisitor = new Find();
     for (final String arg : args.length > 0 ? args : new String[] {"."}) {
         final Path root = Paths.get(arg);
         Files.walkFileTree(root, fileVisitor);
     }
 }

 /** {@inheritDoc} */
 public FileVisitResult preVisitDirectory(final Path dir,
                                          final BasicFileAttributes attrs) {
     if (".svn".equals(dir.getFileName().toString())) {
         return FileVisitResult.SKIP_SUBTREE;
     }
     System.out.println(dir);
     return FileVisitResult.CONTINUE;
 }

 /** {@inheritDoc} */
 public FileVisitResult visitFile(final Path file,
                                  final BasicFileAttributes attrs) {
     System.out.println(file);
     return FileVisitResult.CONTINUE;
 }

该代码的作者指出“visitFile()不为目录调用方法。对于目录,preVisitDirectory()调用方法。”

于 2013-05-27T15:08:52.457 回答