您可以获得所有资源(classpath 上的所有 jar 文件即使没有类也应该可以工作):
Enumeration<URL> resources = null;
try {
resources = Thread.currentThread().getContextClassLoader().getResources(someResource);
} catch (Exception ex) {
//no op
}
if (resources == null || !resources.hasMoreElements()) {
resources = ClasspathReader.class.getClassLoader().getResources(someResource);
}
然后检查当前资源是否为文件。可以直接作为文件处理的文件。
但是你的问题是关于 jar 文件的,所以我不会去那里。
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
if (resource.getProtocol().equals("file")) {
//if it is a file then we can handle it the normal way.
handleFile(resource, namespace);
continue;
}
此时您应该只有 jar:file 资源,所以...
拆分如下所示的字符串:
jar:file:/Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar!/org/node/
进入这个
/Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar
还有这个
/org/node/
这是执行上述操作的代码,无需进行烦人的错误检查。 :)
String[] split = resource.toString().split(":");
String[] split2 = split[2].split("!");
String zipFileName = split2[0];
String sresource = split2[1];
System.out.printf("After split zip file name = %s," +
" \nresource in zip %s \n", zipFileName, sresource);
现在我们有了 zip 文件名,所以我们可以阅读它:
ZipFile zipFile = new ZipFile(zipFileName);
现在我们可以遍历它的条目:
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
/* If it is a directory, then skip it. */
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
System.out.printf("zip entry name %s \n", entryName);
看看它是否以我们正在寻找的资源开头。
if (!entryName.startsWith(someResource)) {
continue;
}
我之前做了两个技巧来查看它是否是一个目录
boolean isDir = !someResource.endsWith(".txt");
这仅有效,因为我正在寻找以 .txt 结尾的资源,并且我假设如果它不以 .txt 结尾,那么它是一个目录 /foo/dir 和 /foo/dir/ 都可以。
另一个技巧是这样的:
if (someResource.startsWith("/")) {
someResource = someResource.substring(1);
}
类路径资源永远不能真正以斜杠开头。逻辑上他们这样做,但实际上你必须剥离它。这是类路径资源的已知行为。除非资源在 jar 文件中,否则它与斜线一起使用。最重要的是,通过剥离它,它总是有效的。
我们需要得到该死的东西的实际文件名。条目名称中的文件名部分。
其中/foo/bar/foo/bee/bar.txt,我们想要'bar.txt',它是文件名。回到我们的 while 循环内部。
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
...
String entryName = entry.getName(); //entry is zipEntry
String fileName = entryName.substring(entryName.lastIndexOf("/") + 1);
/** See if the file starts with our namespace and ends with our extension. */
if (fileName.startsWith(namespace) && fileName.endsWith(".txt")) {
接下来我们查看这些条目是否符合我们的条件,如果符合,则将文件内容读取到 System.out。
try (Reader reader = new InputStreamReader(zipFile.getInputStream(entry))) {
StringBuilder builder = new StringBuilder();
int ch = 0;
while ((ch = reader.read()) != -1) {
builder.append((char) ch);
}
System.out.printf("zip fileName = %s\n\n####\n contents of file %s\n###\n",
entryName, builder);
} catch (Exception ex) {
ex.printStackTrace();//it is an example/proto :)
}
}
您可以在此处查看完整示例:Sleepless in Pleasanton。