Groovy 为什么“readLines”关闭ZipInputStream?

Groovy 为什么“readLines”关闭ZipInputStream?,groovy,Groovy,在Groovy v2.4.1中,我试图读取压缩文件中的文件内容 import java.util.zip.* ZipInputStream zis = new ZipInputStream(new FileInputStream("d:\\temp\\small.zip")) while (zipEntry = zis.nextEntry) { println "Reading ${zipEntry.name}..." def filedata = zis.readLines

在Groovy v2.4.1中,我试图读取压缩文件中的文件内容

import java.util.zip.*

ZipInputStream zis = new ZipInputStream(new FileInputStream("d:\\temp\\small.zip"))

while (zipEntry = zis.nextEntry) {
    println "Reading ${zipEntry.name}..."
    def filedata = zis.readLines()
    println filedata
}
读取zip中的第一个文件后出现以下错误

java.io.IOException:流已关闭

为什么会这样?eachLine和getText也是如此。我还没有在InputStream中尝试过任何其他方法。如何在groovy中读取ZipInputStream中的所有zip文件内容

更新: 虽然我在上面使用了一个文件作为示例,但实际上我只有一个InputStream,没有一个物理文件

InputStream的readLines方法是通过类添加的。当您查看第791行时,您将看到readLines被委托给以Reader作为参数的重写版本。如图所示,此方法在读取流后关闭流。这就是你的例子失败的原因

以下是如何做到这一点:

import java.util.zip.*

def zis = new ZipInputStream(new FileInputStream('lol.zip'))

while (zipEntry = zis.nextEntry) {
    println "Reading $zipEntry.name"
    def output = new ByteArrayOutputStream()
    output << zis
    println "Output: $output"
}
InputStream的readLines方法是通过类添加的。当您查看第791行时,您将看到readLines被委托给以Reader作为参数的重写版本。如图所示,此方法在读取流后关闭流。这就是你的例子失败的原因

以下是如何做到这一点:

import java.util.zip.*

def zis = new ZipInputStream(new FileInputStream('lol.zip'))

while (zipEntry = zis.nextEntry) {
    println "Reading $zipEntry.name"
    def output = new ByteArrayOutputStream()
    output << zis
    println "Output: $output"
}


eachLine和getText的假设是它们处理的是全部内容,因此结束语是适当的简化。在这种情况下,这显然是不合适的。你没有对zipEntry做任何事情。您试图通过执行zis.readLines来读取整个zip文件,而不是读取特定条目。@weston是的,我现在可以看到。ZipInputStream.read的java实现读取到ZipEntry的末尾,然后需要调用nextEntry将标记移动到流中的下一个文件。我在groovy中也这么认为。我错了。你似乎认为你所有的压缩文件都是文本。。。是这样吗?Well read的行为也一样,但readLines在java中根本不可用,它是InputStream上的一种扩展方法。ZipInputStream没有特殊的扩展方法,尽管您可以编写一个:eachLine和getText的假设是它们处理的是全部内容,因此关闭是一个适当的简化。在这种情况下,这显然是不合适的。你没有对zipEntry做任何事情。您试图通过执行zis.readLines来读取整个zip文件,而不是读取特定条目。@weston是的,我现在可以看到。ZipInputStream.read的java实现读取到ZipEntry的末尾,然后需要调用nextEntry将标记移动到流中的下一个文件。我在groovy中也这么认为。我错了。你似乎认为你所有的压缩文件都是文本。。。是这样吗?Well read的行为也一样,但readLines在java中根本不可用,它是InputStream上的一种扩展方法。虽然你可以写一个ZipInputStream,但它没有特殊的扩展方法:在我说之前,它仍然是一个有用的帖子。谢谢你提供了到源代码和文档的链接。我没有在示例代码中提到我只有一个InputStream,所以您的解决方案对我来说不起作用。不过还是要谢谢你@Opal比buffer/while循环更好,是为您实现这一点的Groovy方法…@tim_yates,好主意,但无法实现。你能编辑或提供一个要点吗?@Opal更新了要点,使用了左移位,因为它使用了缓冲技术,所以你不需要自己实现:-在我说之前,这仍然是一篇有用的文章。谢谢你提供了源代码和文档的链接。我没有在示例代码中提到我只有一个InputStream,所以您的解决方案对我来说不起作用。不过还是要谢谢你@Opal比buffer/while循环更好,是为您实现这一点的Groovy方法…@tim_yates,好主意,但无法实现。请编辑或提供要点,好吗?@Opal将要点更新为左移位,因为左移位使用缓冲区技术,因此您无需自行实现:-