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.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With