Правильный способ использования FileVisitor в Java
Я пытаюсь пройти весь путь и его единственный слой подкаталогов. Для каждого файла мне нужно прочитать пять полей данных и вывести их в текстовый файл с разделителями. Я могу читать из одного текстового файла и проверить вывод на экране; после этого я застрял. Я не могу найти правильные параметры для FileVisit. Некоторые конкретные вопросы - комментарии в моем коде, размещенном ниже. И хотя я далеко не так далеко, я хотел бы получить некоторую идею для записи в выходной файл, а именно, является ли место, которое я хочу поместить, наиболее логичным.
Я просмотрел информацию https://stackru.com/questions/9913/java-file-io-compendium и JavaDocs о посетителе файла
http://docs.oracle.com/javase/7/docs/api/index.html?java/nio/file/File Visitor.html. Тем не менее, я все еще не могу заставить File Visitor работать должным образом.
@ 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 ответа
Я немного заржавел на 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 ");"
}
}
Это должно пройти через каталоги и вывести первую строку каждого файла в стандартный вывод. Я не прикасался к Java с 1.6, так что 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;
}
}
С отключенными обобщениями вы должны объявить параметр файла как тип объекта и привести его позже, когда решите использовать его. Как правило, вы не хотите заменять определение интерфейса определением класса или путать их, поскольку они используются для совершенно разных целей.
Джава interface
не может иметь никаких реализаций (т.е. кода) - только сигнатуры методов.
Попробуйте изменить interface
в 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
метод. Здесь у вас есть анонимный класс - здесь вы предоставляете реализацию "на лету".