Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么不能从jar文件中删除条目?_Java_Jar - Fatal编程技术网

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

Java 为什么不能从jar文件中删除条目?,java,jar,Java,Jar,可以使用jar工具向jar文件添加新条目。 可以使用jar工具修改jar文件中的某些条目。 但无法从jar文件中删除某些条目。 为什么?jar文件的目的是打包Java应用程序。在打包应用程序进行部署时,确实不需要删除条目 这里有三种可能的方法 您可以使用winzip或其他一些zip实用程序 您只需将jar与适当的条目一起使用(删除jar并重新打包) 你可以通过编程来做 …有点像,见下文: import java.io.*; import java.util.*; import java.util

可以使用jar工具向jar文件添加新条目。
可以使用jar工具修改jar文件中的某些条目。
但无法从jar文件中删除某些条目。

为什么?

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

这里有三种可能的方法

  • 您可以使用winzip或其他一些zip实用程序
  • 您只需将jar与适当的条目一起使用(删除jar并重新打包)
  • 你可以通过编程来做
  • …有点像,见下文:

    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.");
            }
        }
    }
    
    为什么?

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

    备选方案:

    • 如果您需要手动旋转,只需使用类似的工具即可
    • 如果您想(重新)以编程方式创建jar,您的朋友是谁
    只是为了完整

    一些较旧版本的jar不包含-d选项(用于启用删除),它是后来添加的。因此,请使用较新的jar工具版本或其他归档工具来删除文件

    如果jar已经签名,不要忘记删除签名并放弃它

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

    java示例

    没有人真正回答了原始的
    为什么?
    问题,答案只包含了如何继续这样做的提示

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

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

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

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

    这就是为什么


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

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


    你就是不能用
    jar
    命令。

    @Mike,你为什么这么认为?这与编程无关,只是一个java经常使用的归档工具。它对于Java编程是必不可少的,实际上只有Java程序员使用它。