【问题标题】:modify zip with long pathnames用长路径名修改 zip
【发布时间】:2013-12-29 01:03:39
【问题描述】:

我有一个 jar 文件,我需要从中替换几个类。问题是它们位于一个名称太长的目录中,arch 和 windows 都无法处理。 (所以 jar 文件内的布局包含目录的名称不可能很长)

因此,我无法在物理上创建相同的目录结构并使用“jar uf modded.jar com/”

有没有什么方法/程序/命令/技巧可以让这些文件结束并在那个 jar 文件中的那个位置?

【问题讨论】:

    标签: java jar filesystems zip


    【解决方案1】:

    您可以使用 java.util.zip 包来读取和写入 zip 文件。由于 zip 条目名称只是字符串,因此文件系统对名称长度的限制不是障碍:

    import java.io.InputStream;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.Files;
    import java.nio.file.StandardCopyOption;
    
    import java.util.Collection;
    import java.util.ArrayList;
    import java.util.Map;
    import java.util.LinkedHashMap;
    import java.util.Enumeration;
    import java.util.Objects;
    
    import java.util.logging.Logger;
    import java.util.logging.Level;
    
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipOutputStream;
    import java.util.zip.ZipException;
    
    public class ZipUpdater {
    
        private static final Logger logger =
            Logger.getLogger(ZipUpdater.class.getName());
    
        private final Map<String, Path> changes;
    
        public ZipUpdater(Map<String, Path> changes) {
            this.changes = new LinkedHashMap<>(
                Objects.requireNonNull(changes, "Change list cannot be null"));
        }
    
        public void update(Path zipFile)
        throws IOException,
               ZipException {
    
            Objects.requireNonNull(zipFile, "Zip file cannot be null");
    
            Map<String, Path> changesNeeded = new LinkedHashMap<>(changes);
    
            Path newZipFilePath = Files.createTempFile(null, ".zip");
    
            try (ZipFile oldZipFile = new ZipFile(zipFile.toFile());
                 ZipOutputStream newZipFile = new ZipOutputStream(
                    new BufferedOutputStream(
                        Files.newOutputStream(newZipFilePath)))) {
    
                String comment = oldZipFile.getComment();
                if (comment != null) {
                    newZipFile.setComment(comment);
                }
    
                Enumeration<? extends ZipEntry> oldEntries = oldZipFile.entries();
                while (oldEntries.hasMoreElements()) {
                    ZipEntry entry = oldEntries.nextElement();
    
                    String entryName = entry.getName();
    
                    Path source = changesNeeded.remove(entryName);
    
                    if (source != null) {
                        ZipEntry newEntry = new ZipEntry(entryName);
                        newEntry.setMethod(entry.getMethod());
                        newEntry.setTime(entry.getTime());
                        newEntry.setComment(entry.getComment());
                        newEntry.setExtra(entry.getExtra());
                        newZipFile.putNextEntry(newEntry);
    
                        logger.log(Level.INFO,
                            "Replacing entry \"{0}\" with contents of file \"{1}\"",
                            new Object[] { entryName, source });
    
                        Files.copy(source, newZipFile);
                    } else {
                        ZipEntry newEntry = new ZipEntry(entry);
                        newZipFile.putNextEntry(newEntry);
    
                        logger.log(Level.FINE, "Copying entry {0}", entryName);
    
                        try (InputStream entryData = new BufferedInputStream(
                            oldZipFile.getInputStream(entry))) {
    
                            int b;
                            while ((b = entryData.read()) >= 0) {
                                newZipFile.write(b);
                            }
                        }
                    }
    
                    newZipFile.closeEntry();
                }
            }
    
            if (!changesNeeded.isEmpty()) {
                throw new IOException("The following entries were not found"
                    + " in '" + zipFile + "': " + changesNeeded.keySet());
            }
    
            Files.move(zipFile, Paths.get(zipFile + ".old"),
                StandardCopyOption.REPLACE_EXISTING);
            Files.move(newZipFilePath, zipFile);
        }
    
        public static void main(String[] args)
        throws IOException,
               ZipException {
    
            if (args.length < 3 || (args.length % 2) != 1 ||
                args[0].equals("-?") ||
                args[0].equalsIgnoreCase("-h") ||
                args[0].equalsIgnoreCase("--help")) {
    
                System.err.println("Usage:");
                System.err.println(
                    "java " + ZipUpdater.class.getName() + " <zipfile>"
                    + " <zip-entry> <replacement-file>"
                    + " [ <zip-entry> <replacement-file> ] ...");
                System.exit(2);
            }
    
            Path zipFile = Paths.get(args[0]);
    
            int argCount = args.length;
            Map<String, Path> changes = new LinkedHashMap<>(argCount / 2);
            for (int i = 1; i < argCount; i += 2) {
                String entry = args[i];
                Path replacement = Paths.get(args[i + 1]);
                changes.put(entry, replacement);
            }
    
            ZipUpdater updater = new ZipUpdater(changes);
            updater.update(zipFile);
        }
    }
    

    【讨论】:

    • 可能有点主题,但想让你知道它完美无缺,ty
    猜你喜欢
    • 2015-08-28
    • 1970-01-01
    • 2015-04-24
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多