Read files from sub directories of class path resource folder in spring boot

Techie :

I would like to read files from sub directories of resource folder. I am facing issues with jar execution.

This is my directory structure.

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

Here, I am trying to read config.txt files from all sub directories of Conf folder. I do not know what sub directories Conf will have. I know the classpath till Conf. So, I will give classpath till Conf and trying to get sub directories and files.

I tried to achieve this using ClassPathResource. This works fine if it is file. I am facing issues when it comes to directory. I am using getFile api to get the directory path to walk through that directory for sub directories which is causing issue in jar execution.

Here is my code:

Below code is to read sub directories in Conf folder.

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()));});

Reading each sub directory.

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;
 }

Reading file:

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();
}

Here, I should not use classPathResource.getFile() to get the absolute path because it tries to find file in file system which will not avilable in case of jar. So, I need alternate way to get absolute path of resource directory. I have to pass it to File.walk api to find sub directories and files.

Techie :

As mentioned in the question, first I want to get confX directories then read conf.txt files.

Finally, I could solve my issue as below.

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

This will give all sub directories of Conf directory. Here / at the end in classpath:Conf/*/ is very important. If we do not give / it will work normally but will not work in jar. From the above code block resources[] array will contains directory location like this class path resource [Conf/conf1/] and so on. I need sub directory name to read corresponding file. Here is the code for it.

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();
    }
}

I need to map each txt file with its corresponding directory. That is why I approached this way. If you just need to get files and read you can do it like below. This will list everything under Conf directory.

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=153017&siteId=1
Recommended