Java - 从jar中删除META-INF无法正常工作

时间:2012-01-16 05:36:48

标签: java file io zip minecraft

我目前正在开发一个将mods安装到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();

欢迎任何链接或示例

  • Lachi,Hachi Software CEO

1 个答案:

答案 0 :(得分:0)

问题在于逻辑,让我们来看看它:

  1. 第一次找到META-INF文件夹时,将标志设置为 真正。循环中没有其他任何东西可以发生,所以我们继续
  2. 在下一个循环迭代中,您将标志重置为false并进入 !isMetaInf部分
  3. zip条目已添加到临时zip:

    tmpZip.putNextEntry(ze);

  4. 你写了整个minecraft zip ,从头到尾都写成了临时邮编:

    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
    {
        tmpZip.write(buffer, 0, read);
    }
    tmpZip.closeEntry();
    
  5. 此时你不会突破循环,所以对jar中的每个文件重复这个过程。

  6. 如果你只是删除手动读写循环,你可以允许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();
    }