0

我真的在寻找这个问题的答案。我想创建一个只遍历目录树的通用代码。也许它只是一个包含一个方法的静态类。没问题。对于每个不是目录的文件,它都会做一些. 我认为为这个东西定义一个接口是要做的事情(我现在称之为FileActionInterface.performAction()),但我不确定如何编写目录walker代码来调用这个接口方法(它还不存在)。我已经看到并使用过其他 Java 类,它们有一个“添加接口处理程序()”的方法,然后该类将运行您实现的接口。如果你什么都不丢进去,什么都不会发生。

很抱歉在这里抓住了正确的词。如何编写此目录遍历器代码以调用抽象代码?

PS所有这些都是很好的答案,我已经将它们标记为这样。当一个类对类有一个类似“addInterfaceHandler()”的方法时,他们是如何做到的?我猜这个类有它自己的接口实现,但它可能是空的。然后,当您调用 add() 方法时,您要么替换类的实现,要么像接口实现数组一样添加到它。

我将开始尝试您的不同解决方案。

4

4 回答 4

1
class DirIterator

  interface Callable
    method callback(file) // abstract
  end interface 

  method iterate (dir, callable) {
    for each file in dir
      if (file is Folder) then iterate(file, callable)
      else callable.callback(file)
  }

  // example use
  method main() {
    callable = new Callable{callback(file) {print(file.name)}}; // specify cb for this iteration
    dirIterator.iterate("root_dir_to_iterate/", callable); // start iteration
  }
end class
于 2013-04-18T16:28:49.870 回答
1

作为一个简单的静态方法:

static public walkTree(File dir, Visitor vis) {
    for(File fil: dir.getFiles()) {
        if(fil.isDirectory()) { walkTree(f,vis);      }
        else                  { vis.performAction(f); }
        }
    }

(假设 Visitor 有 performAction 方法。)

于 2013-04-18T16:35:29.723 回答
1

你会写两种类型。第一个是一个接口,它声明了一个方法,如果他们想使用你的walker,他们必须实现。

public interface FileAction {

  void perform(File file) throws IOException;

}

另一个是walker本身:

public final class FileWalker {

  public void scan(File directory, FileAction action) throws IOException {
    if (!directory.isDirectory())
      throw new IllegalArgumentException("Not a directory.");
    File[] sub = directory.listFiles();
    if (sub == null)
      throw new FileNotFoundException("Failed to list directory contents.");
    for (File f : sub) {
      if (f.isDirectory())
        scan(f, action);
      else
        /* This is where you invoke the implementation of the interface. */
        action.perform(f);
    }
  }

}

您的用户将实现您声明的接口。它可以在perform()方法的实现中做任何他们需要的事情,这将由你的文件遍历器调用:

final class SizeCalculator implements FileAction {

  private long total = 0;

  @Override
  public void perform(File file) {
    total += file.length();
  }

  long getTotal() {
    return total;
  }

}

然后他们会一起使用他们的对象和你的对象:

final class Test {

  public static void main(String[] argv) throws IOException {
    SizeCalculator sizer = new SizeCalculator();
    FileWalker walker = new FileWalker();
    File cwd = new File("");
    walker.scan(cwd, sizer);
    System.out.printf("Directory contains %d bytes.%n", sizer.getTotal());
  }

}

如果您使用的是 Java 7,并且您的应用程序实际上是在遍历文件树,那么您应该使用NIO.2 API来遍历文件树。这里,要实现的FileVisitor接口是核心Java库声明的接口。

于 2013-04-18T16:48:48.177 回答
1

您将传入一个实现所述接口的对象。

步行方法将调用该对象上的方法。

类似于Files.walkFileTreeFileVisitor的工作方式。

非常粗略:

public class Walker {
    private Visitor v;
    public Walker(Visitor v) { this.v = v; }
    public walk(File dir) {
        // pseudo-code
        for (File f : dir.getFiles()) {
            if (f.isDir()) {
                walk(f);
            } else {
                v.performAction(f);
            }
        }
    }
}
于 2013-04-18T16:26:19.277 回答