java 列出当前 JAR 文件的目录中的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/346811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listing the files in a directory of the current JAR file
提问by James Van Boxtel
I am making a game in JAVA where I want to come up with a list of files in a certain directory in my jar so I can make sure to have a list of those classes to be used in the game.
我正在用 JAVA 制作一个游戏,我想在我的 jar 中的某个目录中提供一个文件列表,这样我就可以确保有一个要在游戏中使用的类的列表。
For example say in my jar I have a directory
例如在我的 jar 中说我有一个目录
mtd/entity/creep/
I want to get a list of all the .class files in that directory using java code from another class in the jar.
我想使用 jar 中另一个类的 java 代码获取该目录中所有 .class 文件的列表。
What is the best code to do so?
这样做的最佳代码是什么?
采纳答案by VonC
Old java1.4 code, but that would give you the idea:
旧的 java1.4 代码,但这会给你的想法:
private static List getClassesFromJARFile(String jar, String packageName) throws Error
{
final List classes = new ArrayList();
JarInputStream jarFile = null;
try
{
jarFile = new JarInputStream(new FileInputStream(jar));
JarEntry jarEntry;
do
{
try
{
jarEntry = jarFile.getNextJarEntry();
}
catch(IOException ioe)
{
throw new CCException.Error("Unable to get next jar entry from jar file '"+jar+"'", ioe);
}
if (jarEntry != null)
{
extractClassFromJar(jar, packageName, classes, jarEntry);
}
} while (jarEntry != null);
closeJarFile(jarFile);
}
catch(IOException ioe)
{
throw new CCException.Error("Unable to get Jar input stream from '"+jar+"'", ioe);
}
finally
{
closeJarFile(jarFile);
}
return classes;
}
private static void extractClassFromJar(final String jar, final String packageName, final List classes, JarEntry jarEntry) throws Error
{
String className = jarEntry.getName();
if (className.endsWith(".class"))
{
className = className.substring(0, className.length() - ".class".length());
if (className.startsWith(packageName))
{
try
{
classes.add(Class.forName(className.replace('/', '.')));
} catch (ClassNotFoundException cnfe)
{
throw new CCException.Error("unable to find class named " + className.replace('/', '.') + "' within jar '" + jar + "'", cnfe);
}
}
}
}
private static void closeJarFile(final JarInputStream jarFile)
{
if(jarFile != null)
{
try
{
jarFile.close();
}
catch(IOException ioe)
{
mockAction();
}
}
}
回答by elhoce
10 years after the question, I propose an another way to do the job:
提出问题 10 年后,我提出了另一种完成这项工作的方法:
private static void listFilesFromDirectoryInsideAJar(String pathToJar,String directory,String extension) {
try {
JarFile jarFile = new JarFile(pathToJar);
Enumeration<JarEntry> e = jarFile.entries();
while (e.hasMoreElements()) {
JarEntry candidat = e.nextElement();
if (candidat.getName().startsWith(directory) &&
candidat.getName().endsWith(extension))
LOG.info(candidat.getName());
}
} catch (IOException e) {
LOG.error(e.getMessage(),e);
}
}
回答by Tom Hawtin - tackline
Probably the best approach is to list the classes at compile time.
最好的方法可能是在编译时列出类。
There is a fragile runtime approach. Take you Class(MyClass.classof this.getClass()). Call getProtectionDomain. Call getCodeSource. Call getLocation. Call openConnection. (Alternatively open a resource.) Cast to JarURLConnection. Call getJarFile. Call entries. Iterate through checking getName. I really do not recommend this approach.
有一种脆弱的运行时方法。带你Class(MyClass.class的this.getClass())。打电话getProtectionDomain。打电话getCodeSource。打电话getLocation。打电话openConnection。(或者打开一个资源。)投射到JarURLConnection. 打电话getJarFile。打电话entries。迭代检查getName。我真的不推荐这种方法。
回答by Saiyine
Remember that JARfiles are just ZIPfiles renamed, and it's very easy to read the contents of ZIPfiles in Java:
请记住,JAR文件只是ZIP文件改名,这是非常容易阅读的内容ZIP文件在Java中:
File jarName = null;
try
{
jarName = new File (Dir.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
ZipFile zf=new ZipFile(jarName.getAbsoluteFile());
Enumeration e=zf.entries();
while (e.hasMoreElements())
{
ZipEntry ze=(ZipEntry)e.nextElement();
System.out.println(ze.getName());
}
zf.close();
} catch (IOException e)
{
e.printStackTrace();
}
回答by Ilja Preu?
It's not possible, as Java doesn't provide direct access to the jar file the classes are loaded from. You could try to parse the java.class.path system property to find it, but that wouldn't work under all circumstances. Or you could restrict on where the jar file has to reside, or provide the list of the classes in a different way (for example via the manifest file).
这是不可能的,因为 Java 不提供对从中加载类的 jar 文件的直接访问。您可以尝试解析 java.class.path 系统属性以找到它,但这并非在所有情况下都有效。或者您可以限制 jar 文件必须驻留的位置,或以不同的方式(例如通过清单文件)提供类列表。

