为什么 Source.fromInputStream 使用 GZIPInputStream 但不使用 ZipInputStream

Why Source.fromInputStream is working with GZIPInputStream but not with ZipInputStream

我正在尝试流式传输 zip 文件。

以下代码块按预期逐行打印:

val inputStream = new GZIPInputStream(new FileInputStream("/some/path"))
val source = Source.fromInputStream(inputStream)
for(line <- source.getLines) {
  println(line)
}

但是这个什么都不做(它甚至不退出):

val inputStream = new ZipInputStream(new FileInputStream("/some/path"))
val source = Source.fromInputStream(inputStream)
for(line <- source.getLines) {
  println(line)
}

唯一的区别是使用 GZIPInputStream 而不是 ZipInputStream。 class 都实现了 InputStream.

我错过了什么吗?或者有什么解决方法吗?

Gzip 只是一个压缩文件,可以在您阅读 Source 时即时解压缩。 Zip 并不是真正的流,它只是许多 java 误称之一(看看 interface),它更像是一个目录,包含多个文件,您可以通过 ZipEntry,并通过Source分别阅读每一篇。顶层没有真正的内容,只有一个目录列表,所以没有“行”可以通过 Source.

获取

简而言之,您只需遍历条目,为每个条目创建一个新的源。像这样:

   Iterator
     .continually(zip.getNextEntry)
     .takeWhile(_ != null)
     .map { e => 
        e.getName -> Source.fromInputStream(zip).getLines.toList
     } 

(这会在 zip 中创建每个文件名称的 Map 到其整个内容 n 内存,可能根本不是您想要的,只是说明您可以通过以下方式访问该内容的方法Source)