无法从 HTTP 响应中解压缩或获取 blob

Cannot unzip nor get blob from HTTP Response

我正在尝试解压缩 HTTP 请求“响应”中的文件。 我的观点是,在收到响应后,我无法将其解压缩,也无法将其制作成 blob 以在之后对其进行解析。 zip 将始终 return 一个 xml 文件解压缩后的想法是将 XML 转换为 JSON.

这是我试过的代码:

val client = HttpClient.newBuilder().build();
val request = HttpRequest.newBuilder()
    .uri(URI.create("https://donnees.roulez-eco.fr/opendata/instantane"))
    .build();

val response = client.send(request, HttpResponse.BodyHandlers.ofString());

那么 response.body() 就是不可读的,我没有找到将其变成 blob 的正确方法

另外一个直接解压的代码是这个:

val url = URL("https://donnees.roulez-eco.fr/opendata/instantane")
val con = url.openConnection() as HttpURLConnection
con.setRequestProperty("Accept-Encoding", "gzip")
println("Length : " + con.contentLength)

var reader: Reader? = null
reader = InputStreamReader(GZIPInputStream(con.inputStream))

while (true) {
    val ch: Int = reader.read()
    if (ch == -1) {
        break
    }
    print(ch.toChar())
}

但在这种情况下,它不会接受 gzip

有什么想法吗?

您似乎混淆了 zip (an archive format that supports compression) with gzip(一种简单的压缩格式)。

正在下载 https://donnees.roulez-eco.fr/opendata/instantane(例如使用 curl)并检查结果显示它是一个 zip 存档(包含单个文件,PrixCarburants_instantane.xml)。

但您正试图将其解码为 gzip 流(使用 GZIPInputStream),但事实并非如此 — 因此您的问题。

读取 zip 文件比读取 gzip 文件稍微复杂一些,因为它可以容纳多个压缩文件。但是 ZipInputStream 让它变得相当简单:您可以读取第一个 zip 条目(其中包含元数据,包括未压缩的大小),然后继续读取该条目中的实际数据。

更复杂的是这个特定的压缩文件似乎使用 ISO 8859-1 编码,而不是通常的 UTF-8。所以在将字节流转换为文本时需要考虑到这一点。

下面是一些示例代码:

val zipStream = ZipInputStream(con.inputStream)
val entry = zipStream.nextEntry

val reader = InputStreamReader(zipStream, Charset.forName("ISO-8859-1"))
for (i in 1..entry.size)
    print(reader.read().toChar())

显然,一次读取和打印整个 11MB 文件一个字符的效率不是很高!如果 zip 存档有可能有多个条目,则您必须通读所有条目,当您找到名称正确的条目时停下来。但我希望这是一个很好的例证。