Правильный способ использования FileVisitor в java

Я пытаюсь пройти через весь путь и его один слой подкаталогов. Для каждого файла, мне нужно прочитать пять полей данных и вывести их в текстовый файл с разделителями. Я могу читать с один текстовый файл и проверить мой вывод на экране; после этого я застрял. Кажется, я не могу найти правильные параметры для FileVisit. Некоторые конкретные вопросы-это комментарии в моем коде, опубликованные ниже. И хотя я не так далеко, да, я хотел бы получить некоторое представление о запись в выходной файл, а именно, является ли место, которое я хочу поместить, наиболее логичным.

Я просмотрел https://stackoverflow.com/questions/9913/java-file-io-compendium и информация JavaDocs о файле Visitor
http://docs.oracle.com/javase/7/docs/api/index.html?java/nio/file/FileVisitor.html . Однако я все еще не могу заставить FileVisitor работать должным образом.

@Bohemian предложил изменить interface to 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 ответов


Я немного заржавел на 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 ");"
    }
}

Это должно пройти через каталоги и распечатать первую строку каждого файла в std out. Я не касался Java с 1.6, поэтому материал JDK7 для меня тоже немного новый. Я думаю, вы путаетесь в том, что такое класс и что такое интерфейс. В моем примере мы начинаем с базового класса MyDirectoryInspector, чтобы избежать путаницы. Этого достаточно, чтобы дать нам запись программы точка, основной метод, с которого мы начинаем проверку. Звонок в архив.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;
            }
        }

это может иметь больше смысла, если вы только начинаете, чтобы все разошлись. Определите свои классы без inlineing, сделайте это по одному шагу за раз и убедитесь, что вы понимаете каждую часть в изоляции. Мой 2-й пример дает вам 2 отдельных фрагмента, пользовательский посетитель файла, который может использоваться для печати 1-й строки каждого файла, который он посещает, и программу, которая использует его с классом 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 как тип объекта и использовать его позже, когда вы решите его использовать. В общем случае вы не хотите заменять определение интерфейса определением класса или путать их, поскольку они используются для совершенно разных целей.


Java interface can не есть какие - либо реализации (т. е. код) - только метод подписи.

попробуйте изменить interface to class:

public class FileVisitor<T> {
    ...

Теперь, чтобы ответить на ваш пересмотренный пост...

у вас скобка в неправильном месте:

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 метод. То, что у вас здесь есть анонимный класс - вот где можно реализовать "на лету".