我正在尝试在webapp中编写代码,而我的类路径中有一个JAR文件。目的是检查目录是否存在于JAR中。如果是,我需要将文件的所有内容保存在HashMap<String, String>
中的JAR目录中。密钥是文件名,值是每个文件的内容。
File directory = new File(getClass().getClassLoader().getResource(directoryPath).getPath());
System.out.println("PATH IS: " + directory.getPath());
// Check if dirPth exists and is a valid directory
if (!directory.isDirectory()) {
throw new AccessException("Directory \"" + directoryPath + "\" not valid");
}
// Obtain a list of all files under the dirPath
File [] fileList = directory.listFiles();
for (File file : fileList) {
if (file.isFile()) {
// Read the file
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
// Store the file data in the hash
entry.put(file.getName(), sb.toString);
}
}
direcotry.getPath()
的输出是:
文件:\ H:\ apache-tomcat-9.0.27 \ lib \ myConfigurationFiles.jar!\ META-INF \ Maintenance \ xmlFiles \ secondary
这是我要查找的正确文件夹。
这里的Map对象是“ entry”。
现在我不确定为什么direcotry.isDirectory()返回false。它不应该返回true吗?
现在,因为它没有越过第一个异常。我不知道之后会怎样。任何帮助将不胜感激。
答案 0 :(得分:2)
getClass()
对于这样的工作是错误的方法;如果有人继承,它就会中断。正确的方法是改用MyClassName.class
。
getClassLoader().getResource()
也是错误的方法;这会在异乎寻常但可能的情况下中断,其中getClassLoader()
返回null。只需使用getResource
并略微更改路径(添加一个斜杠,或相对于您的类文件写路径)。
您要将字符串file:\H:\apache-tomcat-9.0.27\lib\myConfigurationFiles.jar!\META-INF\Maintenance\xmlFiles\secondary
转换为文件名,然后询问它是否是目录。当然不是;那甚至都不是文件。您需要进行一些字符串操作以从中提取实际的 file :您只需要H:\apache-tomcat-9.0.27\lib\myConfigurationFiles.jar
,将其提供给java.nio.file
API,然后使用它来询问是否它是一个文件(永远不会是目录; jar不是目录)。
请注意,如果您正在读取的资源不是jar,这将无法工作。请注意,类加载API是抽象的:您可能会遇到以下情况:源文件是从头开始生成的,或者是从数据库中加载的,而getResource
方法会生成更多的异常URL来引导。因此,这种代码根本无法使用。确保先可以。
因此:
String urlAsString = MyClassName.class.getResource("MyClassName.class").toString(); // produces a link to yourself.
int start = urlAsString.startsWith("file:jar:") ? 8 : urlAsString.startsWith("file:") ? 4 : 0;
int end = urlAsString.lastIndexOf('!');
String jarFileLoc = urlAsString.substring(start, end);
如果您希望将其应用于实际目录(类文件,此类文件可能来自dirs而不是文件),则可以执行以下操作:
var map = new HashMap<String, String>();
Path root = Paths.get(jarFileLoc);
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
map.put(root.relativize(file), content);
}
});
对于一个罐子,实际上只是一个拉链,它会更像:
var map = new HashMap<String, String>();
Path root = Paths.get(jarFileLoc);
try (var fileIn = Files.newInputStream(root)) {
ZipInputStream zip = new ZipInputStream(fileIn);
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
String content = new String(zip.readAllBytes(), StandardCharsets.UTF_8);
map.put(entry.getName(), content);
}
}
确保您知道什么是字符集,并且此处的UTF_8是正确的。
答案 1 :(得分:1)
在要搜索的jar(java.nio.file.Path
)中输入jarPath
,在jar(String
)中输入directory
作为绝对目录名称,这可能为您服务:
Map<String, String> map = new HashMap<>();
try (FileSystem fs = FileSystems.newFileSystem(jarPath, null)) {
Path dir = fs.getPath(directory);
if (Files.exists(dir)) {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
map.put(file.toString(), Files.readString(file));
return super.visitFile(file, attrs);
}
});
}
}
Files.readString
在Java 11+中可用。对于早期版本,请使用:
new String(Files.readAllBytes(file), StandardCharsets.UTF_8)