当前位置: 首页 > 面试题库 >

在Java中的ZIP存档中修改文本文件

翟弘
2023-03-14
问题内容

我的用例要求我打开一个txt文件,例如abc.txt,该文件位于zip归档文件中,该归档文件包含以下格式的键值对:

key1 = value1

key2 = value2

..依此类推,每个键值对都位于新行中。我必须更改与某个键对应的一个值,然后将文本文件放回存档的新副本中。如何在Java中执行此操作?

到目前为止,我的尝试:

    ZipFile zipFile = new ZipFile("test.zip");
    final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("out.zip"));
    for(Enumeration e = zipFile.entries(); e.hasMoreElements(); ) {
        ZipEntry entryIn = (ZipEntry) e.nextElement();
        if(!entryIn.getName().equalsIgnoreCase("abc.txt")){
            zos.putNextEntry(entryIn);
            InputStream is = zipFile.getInputStream(entryIn);
            byte [] buf = new byte[1024];
            int len;
            while((len = (is.read(buf))) > 0) {            
                zos.write(buf, 0, len);
            }
        }
        else{
            // I'm not sure what to do here
            // Tried a few things and the file gets corrupt
        }
        zos.closeEntry();
    }
    zos.close();

问题答案:

您几乎完全正确。一种可能的原因,该文件显示为已损坏,是您可能已使用过

zos.putNextEntry(entryIn)

在其他部分也是如此。这将在zip文件中创建一个新条目,其中包含来自现有zip文件的信息。现有信息包含条目名称(文件名)及其CRC等信息。

然后,当您尝试更新文本文件并关闭zip文件时,由于条目中定义的CRC与您尝试写入的对象的CRC不同,它将引发错误。

另外,如果您要替换的文本的长度与现有文本的长度不同(即您要替换的文本),则可能会出错

key1 = value1

key1 = val1

归结为您要写入的缓冲区的长度与指定的缓冲区长度不同的问题。

ZipFile zipFile = new ZipFile("test.zip");
final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("out.zip"));
for(Enumeration e = zipFile.entries(); e.hasMoreElements(); ) {
    ZipEntry entryIn = (ZipEntry) e.nextElement();
    if (!entryIn.getName().equalsIgnoreCase("abc.txt")) {
        zos.putNextEntry(entryIn);
        InputStream is = zipFile.getInputStream(entryIn);
        byte[] buf = new byte[1024];
        int len;
        while((len = is.read(buf)) > 0) {            
            zos.write(buf, 0, len);
        }
    }
    else{
        zos.putNextEntry(new ZipEntry("abc.txt"));

        InputStream is = zipFile.getInputStream(entryIn);
        byte[] buf = new byte[1024];
        int len;
        while ((len = (is.read(buf))) > 0) {
            String s = new String(buf);
            if (s.contains("key1=value1")) {
                buf = s.replaceAll("key1=value1", "key1=val2").getBytes();
            }
            zos.write(buf, 0, (len < buf.length) ? len : buf.length);
        }
    }
    zos.closeEntry();
}
zos.close();

以下代码确保即使替换的数据长度小于原始长度,也不会发生IndexOutOfBoundsExceptions。

(len <buf.length)?len:buf.length



 类似资料:
  • 问题内容: 我有一个zip存档,其中包含一堆纯文本文件。我想解析每个文本文件的数据。到目前为止,这是我写的内容: 我需要一个RandomAccessFile来做到这一点吗?我在拥有ZipInputStream的地方迷路了。 问题答案: 不,您不需要。首先获取此zip文件条目的数据: 然后将其包装为(从二进制解码为文本)和a (一次读取一行): 然后像往常一样从中读取行。像往常一样将所有适当的位包装

  • 我一直在尝试读取ZIP存档中的PHP文件。我编写了以下代码,它可以读取文本文档和回显而没有错误,但当我用PHP文件测试时,什么都没有出现。那么我可以做些什么来读取PHP文件而不提取呢? 提前感谢!

  • 修改文档 你现在已经学会了控制光标、打开文件、切换文件、并在文件中查找内容,这些操作都是在 Vim 的 normal 模式下进行的。现在,是时候进入 Vim 的另外一种模式 —— insert 模式,学习一下如何修改文件了。 插入 i 当前字符前插入 a 当前字符后插入 I 行首插入 A 行尾插入 o 在下一行插入 O 在上一行插入 注意:以上任何一个命令都会使 Vim 进入 insert 模式,

  • 我试图在ZIP文件内创建一个ZIP文件,以重新构建以前在内存中的zip结构,我在Java。 我失败了,因为我得到了一个错误的内部ZIP内创建的初始ZIP文件。文件已损坏。当试图打开它时,我得到一个“文件的意外结局”。 我得到了这个结构: -input.zip--InnerInput.zip 代码使用java Stack和Map在内存中解压。然后它创建input2.zip,内部nput.zip。 总

  • 问题内容: 我想修改jar中的文件。是否可以在我的应用程序中执行此操作而无需提取并重新创建? 我要修改的文件是配置文件,主要是基于xml的文件。 我感兴趣的原因是,如果我将其解压缩,则无法再次创建.exe文件。 问题答案: 我想修改中的文件。是否可以在我的应用程序中执行此操作而无需提取并重新创建? 我要修改的文件是配置文件,主要是基于的文件。 我感兴趣的原因是,如果我将其解压缩,则你可以将u选项用

  • 问题内容: 我使用a 来处理文档中的任何更改。而用户键入我想删除的内容JTextPane并插入 自定义文本。无法在中更改文档,而是在此处说一个解决方案:在Java的使用文档侦听器时,但我 问题答案: 实际上仅对更改通知有用,决不能用于修改文本字段/文档。 而是使用 检查这里的例子 费耶 您问题的根源是在文档更新时通知。尝试修改文档(除了可能导致无限循环),将文档置于无效状态,因此是异常 更新了一个