为什么不可能从jar文件中删除条目?

时间:2010-06-15 16:27:10

标签: java jar

可以使用jar工具向jar文件添加新条目 可以使用jar工具修改jar文件中的一些条目 但是从jar文件中删除一些条目是不可能的 为什么呢?

6 个答案:

答案 0 :(得分:4)

没有人真正回答了原来的Why?问题,答案只包含了如何仍然提供的提示。

为什么?

Jar和zip文件是压缩文件,包含一组通常称为条目的文件或指令。 jar / zip文件的结构/格式是条目的 sequencial 枚举(除了zip文件格式标题)。

每个条目都有一个标题,其中包含有关条目的信息,例如它的名称,类型,字节长度(和其他)。

现在采用这个顺序条目列表,您将如何从文件中间删除条目?它会留下一个洞#34;在文件的中间。删除条目的唯一方法(无需重新创建没有可删除条目的存档)将需要从当前(可删除)条目的开头后开始复制zip文件内容,并截断zip文件长度与删除条目的长度。

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

这就是原因。

此结构允许轻松添加新条目,因为它们可以轻松地附加到文件末尾,但是(条目)删除无法有效执行。

答案 1 :(得分:3)

jar文件的目的是打包Java应用程序。在打包部署应用程序时,实际上不需要删除条目。

以下是三种可能的方法。

  1. 您可以使用winzip或其他一些zip实用程序
  2. 您可以使用带有正确条目的jar(删除jar和重新包装)。
  3. 你可以用编程方式做到这一点......
  4. ...有点,见下文:

    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.");
            }
        }
    }
    

答案 2 :(得分:2)

  

为什么?

可能因为jar命令类似于unix命令tar。两者都是创建档案而不是为了管理档案。

变质剂:

  • 如果您需要手动旋转,只需使用7-zip等工具。
  • 如果你想(以编程方式)创建jar,ant是你的朋友

答案 3 :(得分:1)

要完成。

某些旧版本的jar不包含-d选项(启用删除),稍后会添加。因此,使用较新的jar工具版本或其他一个存档工具替代方法来删除文件。

如果罐子已签名,请不要忘记删除签名并将其辞职

答案 4 :(得分:0)

使用cmd命令 - zip -d c:/path/path/file.jar path / path / file.XMLSchema

关于java的例子 http://www.mkyong.com/java/how-to-execute-shell-command-from-java/

答案 5 :(得分:0)

这不可能。您可以使用任何zip实用程序来完成。

您无法使用jar命令。