【问题标题】:How to unzip file from InputStream如何从 InputStream 中解压文件
【发布时间】:2015-11-12 14:14:38
【问题描述】:

我正在尝试从服务器获取一个 zip 文件。 我使用 HttpURLConnection 来获取 InputStream,这就是我所拥有的:

myInputStream.toString().getBytes().toString()  is equal to [B@4.....

byte[] bytes = Base64.decode(myInputStream.toString(), Base64.DEFAULT);
String string = new String(bytes, "UTF-8");
string == �&ܢ��z�m����y....

我真的尝试解压缩这个文件,但没有任何效果,还有很多问题,我应该使用 GZIPInputStream 还是 ZipInputStream?我是否必须将此流保存为文件,或者我可以在 InputStream 上工作

请帮忙,我的老板已经不耐烦了:O 我不知道这个文件里有什么我必须找出:)

【问题讨论】:

  • 检查this 下载
  • 将此 zip 文件写入 sdcard,然后尝试解压缩。不要忘记授予读写权限
  • inputStream.toString() 的使用肯定不会像您认为的那样。就像java.io.File.toString() 不会将文件的 contents 打印为 String,而是打印其他内容(文件的路径),如果您对内容感兴趣,这是无用的。

标签: java android zip unzip


【解决方案1】:

GZipInputStream 和 ZipInputStream 是两种不同的格式。 https://en.wikipedia.org/wiki/Gzip

直接从流中检索字符串不是一个好主意。从 InputStream 中,您可以创建一个 File 并使用 FileOutputStream 将数据写入其中。

Base 64 解码是另一回事。如果您的流已经在上游解码了格式,那没关系;否则你必须用另一个解码 Base64 格式的输入流来封装你的流。 最佳做法是使用缓冲区来避免内存溢出。

这里有一些 Kotlin 代码将 InputStream 解压缩到一个文件中。 (比java简单,因为byte[]的管理比较繁琐):

val fileBinaryDecompress = File(..path..)
val outputStream = FileOutputStream(fileBinaryDecompress)

readFromStream(ZipInputStream(myInputStream), BUFFER_SIZE_BYTES,
    object : ReadBytes {
         override fun read(buffer: ByteArray) {
             outputStream.write(buffer)
         }
    })
outputStream.close()

interface ReadBytes {
    /**
     * Called after each buffer fill
     * @param buffer filled
     */
    @Throws(IOException::class)
    fun read(buffer: ByteArray)
}

@Throws(IOException::class)
fun readFromStream(inputStream: InputStream, bufferSize: Int, readBytes: ReadBytes) {
    val buffer = ByteArray(bufferSize)
    var read = 0
    while (read != -1) {
        read = inputStream.read(buffer, 0, buffer.size)
        if (read != -1) {
            val optimizedBuffer: ByteArray = if (buffer.size == read) {
                buffer
            } else {
                buffer.copyOf(read)
            }
            readBytes.read(optimizedBuffer)
        }
    }
}

如果您想从服务器获取文件而不解压缩,请删除 ZipInputStream() 装饰器。

【讨论】:

    【解决方案2】:

    基本上通过将inputStream 设置为GZIPInputStream 应该能够读取实际内容。 同样为了简单起见,使用来自apache.commonsIOUtils 包让您的生活变得轻松

    这对我有用:

        InputStream is ; //initialize you IS
        is = new GZIPInputStream(is);
        byte[] bytes = IOUtils.toByteArray(is);
        String s = new String(bytes);
        System.out.println(s);
    

    【讨论】:

    • 虽然这段代码可能会解决 OP 的问题,但几句话的解释会对以后的读者更有帮助。
    • @TheThom 是的,你是对的伙伴,抱歉,我在发帖时有点忙。我已经编辑了我的帖子。
    【解决方案3】:

    通常,GZIPInputStream 或 ZipInputStream 之间没有显着差异,所以如果有的话,两者都应该工作。

    接下来,您需要确定压缩流是 Base64 编码的,还是将一些 Base64 编码的内容放入压缩流中 - 从您提出的问题来看,这似乎是后一种选择。

    所以你应该试试

    ZipInputStream zis = new ZipInputStream( myInputStream );
    ZipEntry ze = zis.getNextEntry();
    InputStream is = zis.getInputStream( ze );
    

    然后从那里继续...

    【讨论】:

    • 垃圾。一种是流压缩方法:另一种是用于压缩文件集的系统。
    • @EJP:即使声明某些东西是垃圾,正确的措辞也值得赞赏:一种是流压缩方法(GZIPInputStream),另一种是压缩文件集的方法(ZipInputStream)。还有更多详细信息为什么答案应该是垃圾也很好 - 当你知道更多时,你为什么不回答这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    • 2021-03-15
    • 2017-01-19
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    相关资源
    最近更新 更多