当前位置: 首页 > 面试题库 >

从代码更新.JAR的内容

丁均
2023-03-14
问题内容

我正在制作需要更新的游戏。

我有两个JAR文件:Update.JarGame.Jar 基本上,我希望能够在不完全覆盖Game.Jar的情况下对其进行修改

我想要:

  1. 从代码中将Jar文件作为Zip文件打开
  2. 替换/添加一些资源
  3. 重新打包Jar文件。

有没有简单的方法或类可以做到这一点?如果没有,那么最干净的方法是什么?


问题答案:

Java JAR文件是普通的ZIP文件。因此,您可以使用处理ZIP的代码来打开和修改它。

这是一个有效的代码片段(由David提供):

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class JarUpdater {
    public static void main(String[] args) {

        File[] contents = {new File("F:\\ResourceTest.txt"),
                           new File("F:\\ResourceTest2.bmp")};

        File jarFile = new File("F:\\RepackMe.jar");

        try {
            updateZipFile(jarFile, contents);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void updateZipFile(File zipFile,
             File[] files) throws IOException {
               // get a temp file
        File tempFile = File.createTempFile(zipFile.getName(), null);
               // delete it, otherwise you cannot rename your existing zip to it.
        tempFile.delete();

        boolean renameOk=zipFile.renameTo(tempFile);
        if (!renameOk)
        {
            throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
        }
        byte[] buf = new byte[1024];

        ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));

        ZipEntry entry = zin.getNextEntry();
        while (entry != null) {
            String name = entry.getName();
            boolean notInFiles = true;
            for (File f : files) {
                if (f.getName().equals(name)) {
                    notInFiles = false;
                    break;
                }
            }
            if (notInFiles) {
                // Add ZIP entry to output stream.
                out.putNextEntry(new ZipEntry(name));
                // Transfer bytes from the ZIP file to the output file
                int len;
                while ((len = zin.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            }
            entry = zin.getNextEntry();
        }
        // Close the streams        
        zin.close();
        // Compress the files
        for (int i = 0; i < files.length; i++) {
            InputStream in = new FileInputStream(files[i]);
            // Add ZIP entry to output stream.
            out.putNextEntry(new ZipEntry(files[i].getName()));
            // Transfer bytes from the file to the ZIP file
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            // Complete the entry
            out.closeEntry();
            in.close();
        }
        // Complete the ZIP file
        out.close();
        tempFile.delete();
    }
}


 类似资料:
  • 问题内容: 我是Jenkins Plugin开发的新手,所以请问这个问题很愚蠢。我目前正在开发Jenkins插件,该插件提供了非常小的配置选项列表,如所附的屏幕快照所示。 该表单是使用Jelly脚本设计的。我必须从Java代码更新作业的config.xml文件中由表单提交的这些参数。谁能在我的Java代码中建议更新作业的当前config.xml的方法吗? 谢谢 问题答案: 经过一些研究,我已经知道

  • 我正在尝试从命令行更新Xcode。最初我试着跑步: 这导致了以下消息: 所以问题仍然存在,有没有办法从命令行更新Xcode?

  • 所以,我想创建一个新的BouncyCastle 1.47罐子,它不是OSGi罐子。我已经从他们的站点下载了源代码(JDK1.5-1.7的“JCE with provider and lightweight API”下的bcprov-jdk15on-147.tar.gz文件),但是当我提取它和源代码时,我看不到构建脚本。看看他们的维基,他们说这应该是一个使用ant的简单案例。 以前有人这样做过吗,能

  • 我的程序正在尝试从JFreeChart的旧版本升级,我们正在使用ant编译JFreeChart并将其作为一个组件导入。jar文件。我正在尝试将新的源代码(我在他们的网站上找不到jar)放到一个工作环境中。jar文件,通过使用: 当试图用新代码编译时。jar文件。我得到的错误是“package org.jfree.chart”不存在。我如何使用更新程序。最新JFreeChart版本的jar文件?

  • 问题内容: 在后面的代码中设置很容易,但是这会覆盖现有类。 我需要设置某些元素,并且我想应用一种样式作为视觉提示,说明该项目不能更改…很容易: 但是有时我 还 需要更改相同的元素,这意味着我将需要删除设置的CSS类,而不删除可能已分配的任何其他样式。 最好的方法是什么? 问题答案: 我采用了AnthonyWJones的原始代码并对其进行了修改,以使其在任何情况下均能正常工作:

  • 问题内容: 这可能看起来很奇怪。 我已经用Java(在Eclipse中)编写了代码。然后,我对代码进行了一些修改。现在,我正在尝试运行新代码(已修改),但是它仍然为我提供了先前代码的输出。 我在代码中放置了很少的调试点,但是它跳过了一些调试点(尽管它应该在它们处停止)并在某个调试点处停止,但是即使在这里,它也调用了先前代码中存在的方法。位置(尽管我已经对此发表了评论)。从某个地方看来,它仍然在调试