سؤال

أقوم بإنشاء لعبة بلغة JAVA حيث أريد الحصول على قائمة بالملفات الموجودة في دليل معين في الجرة الخاصة بي حتى أتمكن من التأكد من وجود قائمة بهذه الفئات التي سيتم استخدامها في اللعبة.

على سبيل المثال، قل في الجرة الخاصة بي لدي دليل

mtd/entity/creep/

أريد الحصول على قائمة بجميع ملفات .class الموجودة في هذا الدليل باستخدام كود جافا من فئة أخرى في الجرة.

ما هو الكود الأفضل للقيام بذلك؟

هل كانت مفيدة؟

المحلول

رمز 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();
        }
    }
}

نصائح أخرى

ربما يكون أفضل أسلوب هو إدراج الفئات في وقت الترجمة.

هناك نهج هش وقت التشغيل.يأخذك Class (MyClass.class ل this.getClass()).يتصل getProtectionDomain.يتصل getCodeSource.يتصل getLocation.يتصل openConnection.(بدلاً من ذلك، افتح أحد الموارد.) إرسال إلى JarURLConnection.يتصل getJarFile.يتصل entries.التكرار من خلال التحقق getName.أنا حقا لا أوصي بهذا النهج.

تذكر ذلك إناء الملفات فقط أَزِيز تم إعادة تسمية الملفات ، ومن السهل جدًا قراءة محتويات أَزِيز الملفات في جافا:

    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);
        }
    }

هذا غير ممكن ، لأن Java لا توفر وصولًا مباشرًا إلى ملف JAR الذي يتم تحميل الفئات منها. يمكنك محاولة تحليل خاصية نظام java.class.path للعثور عليها ، لكن هذا لن يعمل في جميع الظروف. أو يمكنك تقييد المكان الذي يجب أن يقيم فيه ملف JAR ، أو توفير قائمة الفئات بطريقة مختلفة (على سبيل المثال عبر ملف البيان).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top