Я делаю игру на JAVA, где я хочу создать список файлов в определенном каталоге в моей банке, чтобы я мог убедиться, что у меня есть список этих классов, которые будут использоваться в игре.
Например, скажем, в моей банке у меня есть каталог
mtd/entity/creep/
Я хочу получить список всех файлов .class в этом каталоге используя Java-код из другого класса в банке.
Какой код лучше всего для этого?




Старый код 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();
}
}
}
О, это именно то, что мне нужно прямо сейчас - спасибо !!
Это невозможно, поскольку Java не предоставляет прямого доступа к файлу jar, из которого загружаются классы. Вы можете попробовать проанализировать системное свойство java.class.path, чтобы найти его, но это не сработает ни при каких обстоятельствах. Или вы можете ограничить, где должен находиться файл jar, или предоставить список классов другим способом (например, через файл манифеста).
что не так в этом ответе? Я предполагал, что более серьезной проблемой будет поиск пути к файлу jar - на самом деле извлечение содержимого должно быть довольно тривиальным.
Вероятно, лучший подход - перечислить классы во время компиляции.
Это хрупкий подход во время выполнения. Возьмем, к примеру, Class (MyClass.class из this.getClass()). Позвоните в getProtectionDomain. Позвоните в getCodeSource. Позвоните в getLocation. Позвоните в openConnection. (Или откройте ресурс.) Транслировать на JarURLConnection. Позвоните в getJarFile. Позвоните в entries. Выполните итерацию, проверив getName. Я действительно не рекомендую такой подход.
Помните, что файлы БАНКА - это просто файлы 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();
}
Спустя 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);
}
}
После того, как я немного поигрался с этим, я заставил его работать. Большое спасибо!