我想从资源文件夹的子目录中读取文件。 我在执行jar时遇到问题。
这是我的目录结构。
src/main/resources
|_ Conf
|_ conf1
|_ config.txt
|_ conf2
|_ config.txt
在这里,我正在尝试从config.txt
文件夹的所有子目录中读取Conf
个文件。我不知道Conf
会有什么子目录。我知道类路径直到Conf
。因此,我将提供类路径直到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才能找到子目录和文件。
答案 0 :(得分:0)
如问题中所述,首先我要获取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/*/
非常重要。如果我们不提供/
,它将正常运行,但不能在jar中运行。
在上面的代码块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();
}
}
我需要将每个txt文件与其对应的目录进行映射。这就是为什么我采用这种方式。如果您只需要获取文件并阅读,则可以按照以下步骤进行操作。这将列出Conf
目录下的所有内容。
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
try {
Resource resources[] = resolver.getResources("classpath:Conf/**");
} catch (IOException e) {
e.printStackTrace();
}
答案 1 :(得分:0)
尝试以下代码。它可以最多扫描n个级别的所需文件,可以使用以下代码中的maxDepth变量指定该文件
// 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();
}