2016-09-03 5 views
3

Мне нужно разработать сканер файлов в Java с помощью следующих опций/параметров:Glob понимание

  1. Один каталог
  2. один или более шаблон * .xml, * .txt, * test.csv
  3. Переключатель для рекурсивного

Я думаю, что лучше всего было бы что-то вроде этого:

public class FileScanningTest { 

    public static void main(String[] args) throws IOException { 

     String directory = "C:\\tmp\\scanning\\"; 
     String glob  = "**/*.xml"; 
     Boolean rekursiv = false; 

     final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:"+glob); 

     Files.walkFileTree(Paths.get(directory), new SimpleFileVisitor<Path>() { 

      @Override 
      public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { 
       if (pathMatcher.matches(path)) { 
        System.out.println(path); 
       } 
       return FileVisitResult.CONTINUE; 
      } 

      @Override 
      public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { 
       return FileVisitResult.CONTINUE; 
      } 
     }); 

    } 

} 

Я не понимаю, почему я должен поставить «** /» перед моим фактическим рисунком. Также это делает сканирование рекурсивным. Если я удалю ** /, приложение больше ничего не находит.

https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob говорит, что ** означает рекурсивный, но почему это не работает, если я удалю это?

Может ли кто-нибудь дать мне подсказку?

Спасибо всем и имеет хорошие выходные

ответ

2

Чтобы найти здесь *.xml с помощью glob, начинающегося с каталога /tmp/scanning/, пожалуйста, взгляните на этот образец. Он работает с Linux Ubuntu и делает то, что вы хотите. Он работает как утилита поиска Unix. Я не тестировал его на других ОС, кроме Ubuntu, но вам нужно только изменить разделитель имен файлов.

import java.io.*; 
import java.nio.file.*; 
import java.nio.file.attribute.*; 

import static java.nio.file.FileVisitResult.*; 
import static java.nio.file.FileVisitOption.*; 

import java.util.*; 


public class FileScanningTest { 

    public static class Finder 
      extends SimpleFileVisitor<Path> { 

     private final PathMatcher matcher; 
     private int numMatches = 0; 

     Finder(String pattern) { 
      matcher = FileSystems.getDefault() 
        .getPathMatcher("glob:" + pattern); 
     } 

     // Compares the glob pattern against 
     // the file or directory name. 
     void find(Path file) { 
      Path name = file.getFileName(); 
      if (name != null && matcher.matches(name)) { 
       numMatches++; 
       System.out.println(file); 
      } 
     } 

     // Prints the total number of 
     // matches to standard out. 
     void done() { 
      System.out.println("Matched: " 
        + numMatches); 
     } 

     // Invoke the pattern matching 
     // method on each file. 
     @Override 
     public FileVisitResult visitFile(Path file, 
             BasicFileAttributes attrs) { 
      find(file); 
      return CONTINUE; 
     } 

     // Invoke the pattern matching 
     // method on each directory. 
     @Override 
     public FileVisitResult preVisitDirectory(Path dir, 
               BasicFileAttributes attrs) { 
      find(dir); 
      return CONTINUE; 
     } 

     @Override 
     public FileVisitResult visitFileFailed(Path file, 
               IOException exc) { 
      System.err.println(exc); 
      return CONTINUE; 
     } 
    } 


    public static void main(String[] args) 
      throws IOException { 
     boolean recursive = false; 
     Path startingDir = Paths.get("/tmp/scanning"); 
     String pattern = "*.{html,xml}"; 

     Finder finder = new Finder(pattern); 
     if (!recursive) { 
      Path dir = startingDir; 
      List<File> files = new ArrayList<>(); 
      try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{xml,html}")) { 
       for (Path entry : stream) { 
        files.add(entry.toFile()); 
       } 

       for (File xmlfile : files) { 
        System.out.println(xmlfile); 
       } 
      } catch (IOException x) { 
       throw new RuntimeException(String.format("error reading folder %s: %s", 
         dir, 
         x.getMessage()), 
         x); 
      } 
     } else {  
      Files.walkFileTree(startingDir, finder); 
      finder.done(); 
     } 

    } 
} 

Тест

~> java FileScanningTest 
/tmp/scanning/dir2/test2.xml 
/tmp/scanning/blah.xml 
Matched: 2 

Если вы хотите, чтобы соответствовать либо *.xml или test3.html, то вы можете использовать этот шаблон: String pattern = "{*.xml,test3.html}";

+0

Спасибо. Это работает и на платформах Windows. Но как я могу отключить рекурсивное сканирование? У нас есть возможность отключить рекурсивное сканирование. И есть ли способ иметь несколько разных моделей одновременно? – Hauke

+0

@ Hauke ​​Да. Чтобы отключить рекурсивное сканирование, все, что вам нужно, это вариант от пользователя, например. 'args [0]', и вы можете использовать несколько разных шаблонов с регулярным выражением. Я могу показать вам или вы можете задать новый вопрос. Я могу обновить код, который я разместил в соответствии с вашими спецификациями. Мне также нравится узнать, как это делается на Java (я делаю это много на C.) –

+1

Если бы вы могли обновить свой код, это было бы здорово.Это всего лишь класс тестирования, но с логическим флагом «рекурсивный» было бы нормально, а не анализировать аргументы приложения. Спасибо за вашу помощь – Hauke

1

Разница между * и ** что * никогда не будет соответствовать каталогу разделителя (/ или \ в зависимости от вашей операционной системы), но ** волю. Учитывая файл дерево, как это:

a/ 
    b.xml 
c/ 
    a.xml 
da.xml 

Узор *a.xml будет соответствовать только da.xml (не c/a.xml так, что содержит /), в то время как модель **a.xml будет соответствовать как da.xml и c/a.xml, и шаблон a**.xml будет соответствовать только a/b.xml ,

+0

Спасибо за информацию. Это означает, что я могу использовать шаблон * a.xml, если я уже размещен в каталоге, не указав весь путь? – Hauke

 Смежные вопросы

  • Нет связанных вопросов^_^