ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

使用Java修改ZIP存档中的文本文件

2019-09-27 10:02:04  阅读:599  来源: 互联网

标签:file-handling java zip


我的用例要求我打开一个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

标签:file-handling,java,zip
来源: https://codeday.me/bug/20190927/1823516.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有