【问题标题】:Java - Removal of META-INF from jar not workingJava - 从 jar 中删除 META-INF 不起作用
【发布时间】:2012-01-16 05:36:47
【问题描述】:

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

欢迎提供任何链接或示例

  • Liam,Hachi Software 首席执行官

【问题讨论】:

  • 我不确定您是否阅读了 SO 许可条款,它是 CC-Wiki,此处的内容可以未经授权使用 (AFAIK),如果您认为它不应该是可分发的,请删除。

标签: java file io zip minecraft


【解决方案1】:

问题出在逻辑上,我们来看看:

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

    tmpZip.putNextEntry(ze);

  4. 您编写整个 minecraft zip,从头到尾进入 temp zip:

    for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
    {
        tmpZip.write(buffer, 0, read);
    }
    tmpZip.closeEntry();
    
  5. 此时您并没有跳出循环,因此对 jar 中的每个文件都重复此过程。

如果您只是简单地删除手动读写循环,您可以在最后调用close() 时让 ZipOutputStream 为您完成所有写入,或者如果您使用 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();
}

【讨论】:

猜你喜欢
  • 2013-02-25
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2020-11-03
相关资源
最近更新 更多