Updating .JAR's contents from code

前端 未结 2 1259
甜味超标
甜味超标 2020-12-07 02:51

I am making a game that needs to be updated.

I have two JAR files: Update.Jar and Game.Jar Basically, I want to be able to modify Game.Jar

相关标签:
2条回答
  • 2020-12-07 03:27

    A Java JAR file is a normal ZIP file. You can therefore open and modify it with code dealing with ZIPs.

    Here's a snippet which works (courtesy of 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();
        }
    }
    
    0 讨论(0)
  • 2020-12-07 03:29

    In Java 7, the best way is to use the built in Zip File System Provider:

    http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html

    i.e.

    import java.util.*;
    import java.net.URI;
    import java.nio.file.Path;
    import java.nio.file.*;
    
    public class ZipFSPUser {
        public static void main(String [] args) throws Throwable {
            Map<String, String> env = new HashMap<>();
            env.put("create", "true");
            // locate file system by using the syntax
            // defined in java.net.JarURLConnection
            URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");
    
           try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
                Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt");
                Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");      
                // copy a file into the zip file
                Files.copy( externalTxtFile,pathInZipfile,
                        StandardCopyOption.REPLACE_EXISTING );
            }
        }
    }
    

    ~

    0 讨论(0)
提交回复
热议问题