Чтение файлов из подкаталогов папки ресурсов пути к классам при весенней загрузке - PullRequest
0 голосов
/ 29 января 2019

Я хотел бы прочитать файлы из подкаталогов папки ресурсов.У меня проблемы с выполнением jar.

Это моя структура каталогов.

src/main/resources |_ Conf |_ conf1 |_ config.txt |_ conf2 |_ config.txt

Здесь я пытаюсь прочитать config.txt файлы из всех подкаталоговиз папки Conf.Я не знаю, какие будут подкаталоги Conf.Я знаю путь к классу до Conf.Итак, я дам classpath до Conf и попытаюсь получить подкаталоги и файлы.

Я пытался добиться этого, используя ClassPathResource.Это прекрасно работает, если это файл.Я сталкиваюсь с проблемами, когда дело доходит до каталога.Я использую getFile api, чтобы получить путь к каталогу, чтобы пройти через этот каталог для подкаталогов, который вызывает проблемы при выполнении jar.

Вот мой код:

Ниже код должен прочитатьподкаталоги в папке Conf.

List<Map<String,String>> list = new ArrayList<Map<String,String>>();
 ClassPathResource classPathResource = new ClassPathResource("Conf");
 File dir = classPathResource.getFile();
 Files.walk(Paths.get(dir.toString()))
     .filter(Files::isDirectory)
      // This is to exempt current dir.
     .filter((Path p)->!p.toString().equals(dir.toString()))
     .forEach(f-> {list.add(readDirectory(f.toString()));});

Чтение каждого подкаталога.

public Map<String, String> readDirectory(String dir) {
     Map<String, String> map = new HashMap<String, String>();
     String confDir = dir.substring(dir.lastIndexOf(File.separator)+1);
    try {
          Files.list(Paths.get(dir))
                   .filter(f->f.toString().matches(".*conf\\.txt"))
           .forEach(file ->approvedTermsMap.put
                               (confDir,readFile(file.toFile())));
    } catch (IOException e) {
        e.printStackTrace();
        }
        return map;
 }

Чтение файла:

public String readFile(File confFile) {

       StringBuffer terms = new StringBuffer();
       try (BufferedReader reader = new BufferedReader(new 
             FileReader(confFile)))
    {
        reader.lines().forEach(term->                    
                             terms.append(term + "|"));
    } catch (FileNotFoundException e) {
            e.printStackTrace();
    } catch (IOException e) {
            e.printStackTrace();
    }
return terms.toString();
}

Здесь я не должен использовать classPathResource.getFile(), чтобы получить абсолютный путь, потому что он пытается найти файл в файловой системе, который не будет доступен в случае jar.Итак, мне нужен альтернативный способ получить абсолютный путь к каталогу ресурсов.Я должен передать его в File.walk API, чтобы найти подкаталоги и файлы.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Попробуйте следующий код.Он может сканировать требуемые файлы до n уровней, которые можно указать с помощью maxDepth varaible в следующем коде

// Finding a file upto x level in File Directory using NIO Files.find
    Path start = Paths.get("/Users/***/Documents/server_pull");
    int maxDepth = 5;
    try(Stream<Path> stream = Files.find(start, 
                                        maxDepth, 
                                        (path, attr) -> String.valueOf(path).endsWith(".txt"))){
        String fileName = stream
                            .sorted()
                            .map(String::valueOf)
                            .filter((path) -> {
                                //System.out.println("In Filter : "+path);
                                return String.valueOf(path).endsWith("config.txt");
                            })
                            .collect(Collectors.joining());
        System.out.println("fileName : "+fileName);
    }catch(Exception e){
        e.printStackTrace();
    }

Другой способ, используя методы Files.walk следующим образом:

// Finding a file upto x level in File Directory using NIO Files.walk

    Path startWalk = Paths.get("/Users/***/Documents/server_pull");
    int depth = 5;
    try( Stream<Path> stream1 = Files.walk(startWalk, 
                                            depth)){
        String walkedFile = stream1
                            .map(String::valueOf)
                            .filter(path -> {
                                return String.valueOf(path).endsWith("config.txt");
                            })
                            .sorted()
                            .collect(Collectors.joining());
        System.out.println("walkedFile = "+walkedFile);

    }catch(Exception e){
        e.printStackTrace();
    }
0 голосов
/ 04 февраля 2019

Как уже упоминалось в вопросе, сначала я хочу получить confX каталоги, а затем прочитать conf.txt файлы.

Наконец, я могу решить свою проблему, как показано ниже.

ClassLoader cl = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
try {
        Resource resources[] = resolver.getResources("classpath:Conf/*/");
} catch (IOException e) {
        e.printStackTrace();
}

Это даст все подкаталоги каталога Conf.Здесь / в конце в classpath:Conf/*/ очень важно.Если мы не дадим /, он будет работать нормально, но не будет работать в банке.Из приведенного выше блока кода resources[] массив будет содержать каталог, как этот class path resource [Conf/conf1/] and so on.Мне нужно имя подкаталога, чтобы прочитать соответствующий файл.Вот код для него.

Arrays.asList(resources).stream()
                        .forEach(resource ->{ 
                                  Pattern dirPattern = Pattern.compile(".*?\\[(.*/(.*?))/\\]$");
                                  if (resource.toString().matches(".*?\\[.*?\\]$")) {
                                      Matcher matcher = dirPattern.matcher(resource.toString());
                                     if (matcher.find()) {
                                        String dir = matcher.group(1);
                                        readFile(dir);
                                      }
                                  }
                             });


public void readFile(String dir)
{

   ClassPathResource classPathResource = new ClassPathResource(dir+ "/conf.txt");
    try (BufferedReader fileReader = new BufferedReader(
            new InputStreamReader(classPathResource2.getInputStream()))) {
        fileReader.lines().forEach(data -> System.out.println(data));
     }catch (IOException e) {
        e.printStackTrace();
    }
}

Мне нужно сопоставить каждый текстовый файл с соответствующим каталогом.Вот почему я подошел таким образом.Если вам просто нужно получить файлы и прочитать их, вы можете сделать это, как показано ниже.Это перечислит все в каталоге Conf.

 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
try {
        Resource resources[] = resolver.getResources("classpath:Conf/**");
} catch (IOException e) {
        e.printStackTrace();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...