在java中使用FileVisitor的正确方法

时间:2012-04-04 15:51:19

标签: io java-7 filevisitor

我试图遍历整个路径及其单层子目录。对于每个文件,我需要读取五个数据字段并将它们输出到分隔的文本文件。我能够从单个文本文件中读取并在屏幕上验证我的输出;之后我被卡住了。我似乎无法为FileVisit找到合适的参数。一些具体问题是我在下面发布的代码中的注释。虽然我不是那么远,但是我想知道写一个输出文件,即我希望把它放在哪个地方是最合乎逻辑的。

我查看了文件访问者的https://stackoverflow.com/questions/9913/java-file-io-compendium和JavaDocs'信息 http://docs.oracle.com/javase/7/docs/api/index.html?java/nio/file/FileVisitor.html。 但是,我仍然无法使FileVisitor正常工作。

@Bohemian建议我将interface更改为class

 import java.nio.files.*;
 public class FileVisitor<T> 
 {
      Path startPath = Paths.get("\\CallGuidesTXT\\");
      Files.walkFileTree(startPath, new SimpleFileVisitor(startPath))
      \\             ^^^^^^    
      \\ errors out, <identifier expected>          
          { 
          @Override
          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
              throws IOException
          {
              Files.list(file);
              return FileVisitResult.CONTINUE;
          }
        // do my file manipulations here, then write the delimited line 
        // of text to a CSV fle...is this the most appropriate place for that 
        // operation in this sample? 
      }  
 }

下面的SSCCE ......但上面版本中的评论指出了我遇到的具体问题。

 import java.nio.*;
 import java.util.*;
 public class FileVisitor<T>
 {
    Path startPath = Paths.get("\\CallGuidesTXT\\");
 }
 Files.walkFileTree(startPath, new SimpleFileVisitor(startPath)  {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
          Files.list(file);
          return FileVisitResult.CONTINUE;
      } 
 });

3 个答案:

答案 0 :(得分:9)

我在Java方面有点生疏,但我对你认为你要去的地方有一个粗略的想法:

import java.nio.files.*;
public class MyDirectoryInspector extends Object 
{
    public static void main(String[] args) {
        Path startPath = Paths.get("\\CallGuidesTXT\\");
        Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() { 
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException
            {
                String firstLine = Files.newBufferedReader(file, Charset.defaultCharset()).readLine();
                System.out.println(firstLine);
                return FileVisitResult.CONTINUE;
            }
        }); // <- you were missing a terminating ");"
    }
}

这应该遍历目录并打印每个文件的第一行到标准输出。我从1.6开始就没有触及过Java,所以JDK7的东西对我来说也有点新鲜。我认为你对什么是类以及什么是界面感到困惑。在我的例子中,我们从一个名为MyDirectoryInspector的基本类开始,以避免混淆。这足以给我们一个程序入口点,这是我们开始检查的主要方法。对Files.walkFileTree的调用需要2个参数,一个开始路径和一个我内联的文件访问者。 (我认为如果你不习惯这种风格,内联可能会让一些人感到困惑。)这是一种在你想要使用它的地方定义实际类的方法。您也可以单独定义SimpleFileVisitor,并为您的调用实例化它,如下所示:

import java.nio.files.*;
public class MyDirectoryInspector extends Object 
{
    public static void main(String[] args) {
        Path startPath = Paths.get("\\CallGuidesTXT\\");
        Files.walkFileTree(startPath, new SimpleFileVisitor<Path>());
    }
}

public class SimpleFileVisitor<Path>()) { 
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException
            {
                String firstLine = Files.newBufferedReader(file, Charset.defaultCharset()).readLine();
                System.out.println(firstLine);
                return FileVisitResult.CONTINUE;
            }
        }

如果你刚刚开始,可能更有意义的是保持一切分开。在没有内联的情况下定义您的类,一次一步,并确保您孤立地理解每个部分。我的第二个示例为您提供了2个单独的部分,一个自定义文件访问者,可用于打印它访问的每个文件的第一行,以及一个将它与JDK Files类一起使用的程序。现在让我们看一下省略语法的另一种方法:

import java.nio.files.*;
public class MyDirectoryInspector extends Object 
{
    public static void main(String[] args) {
        Path startPath = Paths.get("\\CallGuidesTXT\\");
        Files.walkFileTree(startPath, new SimpleFileVisitor());
    }
}

public class SimpleFileVisitor()) { 
            @Override
            public FileVisitResult visitFile(Object file, BasicFileAttributes attrs)
                throws IOException
            {
                String firstLine = Files.newBufferedReader((Path)file, Charset.defaultCharset()).readLine();
                System.out.println(firstLine);
                return FileVisitResult.CONTINUE;
            }
        }

如果遗漏了泛型,则必须将file参数声明为Object类型,并在以后选择使用它时将其强制转换。通常,您不希望将接口定义替换为类定义,或者将两者混淆,因为它们用于完全不同的目的。

答案 1 :(得分:6)

Java interface可以有任何实现(即代码) - 只有方法签名

尝试将interface更改为class

public class FileVisitor<T> {
    ...

答案 2 :(得分:2)

现在回答你修改后的帖子......

你有一个错误位置的支架:

Files.walkFileTree(startPath, new SimpleFileVisitor(startPath) { 
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
          Files.list(file);
          return FileVisitResult.CONTINUE;
      }
  });

我在new SimpleFileVisitor(startPath)之后移动了括号以包含visitFile方法。你在这里有一个anonymous class - 你可以“动态”提供一个实现。