首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么无法从jar文件中删除条目?

为什么无法从jar文件中删除条目?
EN

Stack Overflow用户
提问于 2010-06-16 00:27:10
回答 6查看 4.3K关注 0票数 5

可以使用jar工具将新条目添加到jar文件。

可以使用jar工具修改jar文件中的某些条目。

但无法从jar文件中删除某些条目。

为什么?

EN

回答 6

Stack Overflow用户

发布于 2014-08-22 15:42:17

没有人真正回答了最初的Why?问题,答案只是包含了如何仍然做到这一点的提示。

那么为什么呢?

Jar和zip文件是具有一组文件或目录的压缩文件,通常称为条目。jar/zip文件的结构/格式是条目的顺序枚举(除了zip文件格式头)。

每个条目都有一个头部,其中包含关于条目的信息,例如它的名称、类型、字节长度(以及其他)。

现在看看这个顺序条目列表,您将如何从文件中间删除一个条目?它会在文件中间留下一个“洞”。删除条目(不必在没有可删除条目的情况下重新创建存档)的唯一方法将需要将从条目之后开始的zip文件内容复制到当前(可删除)条目的开头,并且还将zip文件长度截断所删除条目的长度。

想象一下,如果你有一个有几十或几百MB的档案,这意味着什么?如果要删除开头的条目,则必须将文件的几乎全部内容复制回几个字节(或千字节),以避免在文件中留下空白。

这就是为什么。

这种结构允许很容易地添加新条目,因为它们可以很容易地附加到文件的末尾,但是(条目)删除不能有效地执行。

票数 5
EN

Stack Overflow用户

发布于 2010-06-16 01:18:38

jar文件的目的是打包Java应用程序。确实没有必要删除条目,因为您正在打包要部署的应用程序。

这里有三种你可以做到的方法。

  1. 您可以使用winzip或其他一些压缩实用程序
  2. 您可以只使用带有适当条目的jar (删除jar,repackage).
  3. You可以执行此操作programatically...

...sort of,如下所示:

代码语言:javascript
复制
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;


public class JarUpdate
{
    /**
     * main()
     */
    public static void main(String[] args) throws IOException
    {
        // Get the jar name and entry name from the command-line.

        String jarName = args[0];
        String fileName = args[1];

        // Create file descriptors for the jar and a temp jar.

        File jarFile = new File(jarName);
        File tempJarFile = new File(jarName + ".tmp");

        // Open the jar file.

        JarFile jar = new JarFile(jarFile);
        System.out.println(jarName + " opened.");

        // Initialize a flag that will indicate that the jar was updated.

        boolean jarUpdated = false;

        try
        {
            // Create a temp jar file with no manifest. (The manifest will
            // be copied when the entries are copied.)

            Manifest jarManifest = jar.getManifest();
            JarOutputStream tempJar = new JarOutputStream(new FileOutputStream(tempJarFile));

            // Allocate a buffer for reading entry data.

            byte[] buffer = new byte[1024];
            int bytesRead;

            try
            {
                // Open the given file.

                FileInputStream file = new FileInputStream(fileName);

                try
                {
                    // Create a jar entry and add it to the temp jar.

                    JarEntry entry = new JarEntry(fileName);
                    tempJar.putNextEntry(entry);

                    // Read the file and write it to the jar.

                    while ((bytesRead = file.read(buffer)) != -1)
                    {
                        tempJar.write(buffer, 0, bytesRead);
                    }

                    System.out.println(entry.getName() + " added.");
                }
                finally
                {
                    file.close();
                }

                // Loop through the jar entries and add them to the temp jar,
                // skipping the entry that was added to the temp jar already.

                for (Enumeration entries = jar.entries(); entries.hasMoreElements();)
                {
                    // Get the next entry.

                    JarEntry entry = (JarEntry)entries.nextElement();

                    // If the entry has not been added already, add it.

                    if (!entry.getName().equals(fileName))
                    {
                        // Get an input stream for the entry.

                        InputStream entryStream = jar.getInputStream(entry);

                        // Read the entry and write it to the temp jar.

                        tempJar.putNextEntry(entry);

                        while ((bytesRead = entryStream.read(buffer)) != -1)
                        {
                            tempJar.write(buffer, 0, bytesRead);
                        }
                    }
                }

                jarUpdated = true;
            }
            catch (Exception ex)
            {
                System.out.println(ex);

                // Add a stub entry here, so that the jar will close without an
                // exception.

                tempJar.putNextEntry(new JarEntry("stub"));
            }
            finally
            {
                tempJar.close();
            }
        }
        finally
        {
            jar.close();
            System.out.println(jarName + " closed.");

            // If the jar was not updated, delete the temp jar file.

            if (!jarUpdated)
            {
                tempJarFile.delete();
            }
        }

        // If the jar was updated, delete the original jar file and rename the
        // temp jar file to the original name.

        if (jarUpdated)
        {
            jarFile.delete();
            tempJarFile.renameTo(jarFile);
            System.out.println(jarName + " updated.");
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2010-06-16 17:23:45

为什么?

可能是因为jar命令类似于unix命令tar。两者都是用来创建档案,而不是用来管理它们的。

备用项:

如果您需要手动旋转,只需使用像7-zip.

  • If这样的工具,您就可以通过编程方式(重新)创建jar的

是您的朋友

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3047081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档