我正在尝试从jar文件中读取包名称。我的问题是,当我得到URL时,它包含无法识别的表单,要被windows文件识别。
我读过这个解决方案。但这对我没有帮助。将URL转换为普通的windows文件名Java。
directoryURL.toURI().getSchemeSpecificPart()
不转换窗口样式。
这是我的密码。
// Get a File object for the package
URL directoryURL = Thread.currentThread().getContextClassLoader()
.getResource(packageNameSlashed);
logger.info("URI" + directoryURL.toURI());
logger.info("Windows file Name" + directoryURL.toURI().getSchemeSpecificPart());
// build jar file name, then loop through zipped entries
jarFileName = URLDecoder.decode(directoryURL.getFile(), "UTF-8");
jarFileName = jarFileName.substring(0, jarFileName.indexOf(".jar"));
// HERE Throws exception"
jf = new JarFile(jarFileName + ".jar");
while (jarEntries.hasMoreElements()) {
entryName = jarEntries.nextElement().getName();
logger.info("Entry name: " + entryName);
if (entryName.startsWith(packageNameSlashed)
&& entryName.length() > packageNameSlashed.length() + 5
&& entryName.endsWith(".class")) {
entryName = entryName.substring(packageNameSlashed.length() + 1);
packageClassNames.put(entryName, packageName);
}
}
这是日志。
16-02-2015 14:02:15 INFO - URI jar:file:/C:/SVN/AAA/trunk/aaa/client/target/server-1.0.jar!/packageName
16-02-2015 14:02:15 INFO Windows file Name file:/C:/SVN/AAA/trunk/aaa/client/target/server-1.0.jar!/packageName
"jar:…"URL不能识别文件。相反,它标识JAR文件的一个成员。
语法是(粗略地说)"jar:<jar-url>!<path-within-jar>"
,其中本身就是一个URL;例如,您的示例中的"file:"URL。
如果要打开JAR文件并迭代类似的条目,则需要:
-
提取原始URL 的schemeSpecificPart
-
拆分"!"字符上的schemeSpecificPart。
-
将"!"之前的部分解析为URI,然后使用
File(URI)
获取File
。 -
使用
File
打开ZipFile
。 -
在
ZipFile
中查找"!"之后的零件。。。
Stephen的答案包含了您需要的所有元素。
- 使用getResource(package).getURI()或getResoucer(package.toFile可以获得资源的路径
- 对其执行子字符串以提取文件://和!这是您感兴趣的罐子的物理位置的路径
- 在这个子路径上删除新文件,你就有了jar的句柄
- Jar是一个普通的zip文件,并对其进行处理(java.util.zip和网上的手册)
- 列出zip文件的内容(现在您可能需要使用后面的位进行导航!在原始路径中签名),然后您就可以获得类名了
我不确定这是否是实现目标的最佳方式,我会检查类发现(这是你正在尝试做的)是如何在一些开源框架中实现的(例如tomcat使用它,JPA实现来查找实体)。还有一个关于apache的发现项目,但它似乎已经死了一段时间。