Java - удаление META-INF из банки не работает - PullRequest
1 голос
/ 16 января 2012

Я сейчас работаю над приложением, которое устанавливает моды в Minecraft, и я почти закончил версию 3.1DEV, единственное, что меня останавливает, это то, что мой код просто не удалит META-INF, вот мой код

        ZipInputStream modZip = new ZipInputStream(new FileInputStream(mod.getDir()));
        ZipInputStream minecraftZip = new ZipInputStream(new FileInputStream(new File(mcDir + "\\bin\\", "minecraft.jar")));
        ZipOutputStream tmpZip = new ZipOutputStream(new FileOutputStream(new File("temp\\tmp.jar")));
        byte[] buffer = new byte[1024];

        for(ZipEntry ze = modZip.getNextEntry(); ze != null; ze = modZip.getNextEntry())
        {
            tmpZip.putNextEntry(ze);
            for(int read = modZip.read(buffer); read != -1; read = modZip.read(buffer))
            {
                tmpZip.write(buffer, 0, read);
            }
            tmpZip.closeEntry();
        }
        modZip.close();


        for(ZipEntry ze = minecraftZip.getNextEntry(); ze != null; ze = minecraftZip.getNextEntry())
        {
            try
            {
                boolean isMetaInf = false;

                if(ze.getName().contains("META-INF"))
                {
                    isMetaInf = true;
                }

                if(!isMetaInf)
                {
                    tmpZip.putNextEntry(ze);
                    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
                    {
                        tmpZip.write(buffer, 0, read);
                    }
                    tmpZip.closeEntry();
                }
            }
            catch(Exception e)
            {
                continue;
            }
        }
        minecraftZip.close();

        tmpZip.flush();
        tmpZip.close();

        File tmp = new File("temp//tmp.jar");
        tmp.renameTo(new File("temp//minecraft.jar"));
        File minecraft = new File(mcDir + "\\bin\\minecraft.jar");
        minecraft.delete();
        FileUtils.copyFile(new File("temp\\minecraft.jar"), minecraft);
        tmp.delete();

Любые ссылки или примеры приветствуются

  • Лиам, генеральный директор Hachi Software

1 Ответ

0 голосов
/ 16 марта 2014

Проблема с логикой, давайте пройдемся по ней:

  1. При первом обнаружении папки META-INF вы устанавливаете флаг в значение true.Ничего другого в цикле не может произойти, поэтому мы продолжаем
  2. На следующей итерации цикла вы сбрасываете флаг на false и переходите в раздел !isMetaInf
  3. Запись zipдобавлено к временному почтовому индексу:

    tmpZip.putNextEntry(ze);

  4. Вы пишете весь почтовый индекс Minecraft , от начала до конца, во временный почтовый индекс:

    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
    {
        tmpZip.write(buffer, 0, read);
    }
    tmpZip.closeEntry();
    
  5. На этом этапе вы не выходите из цикла, поэтому этот процесс повторяется для каждого файла в банке.

Если вы просто удалите ручной цикл чтения и записи, вы можете позволить ZipOutputStream делать всю запись за вас, когда вы в конце вызываете close(), или, если вы используете Java 7, вы можете сделать этот код очень простым, попробовав-с ресурсами:

public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
    try (final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
         final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip)))
    {
        ZipEntry entry;
        while((entry = zip.getNextEntry()) != null)
        {
            if(!entry.getName().contains("META-INF"))
            {
                zop.putNextEntry(entry);
            }
        }
    }
}

public static void main(String[] args) throws IOException
{
    copyWithoutMetaInf("1.6.4.jar", "copy.jar");
}

или без, для более старых версий:

public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
    final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
    final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip));
    ZipEntry entry;
    while((entry = zip.getNextEntry()) != null)
    {
        if(!entry.getName().contains("META-INF"))
        {
            zop.putNextEntry(entry);
        }
    }
    zip.close();
    zop.close();
}
...