10

我有一个 servlet 正在向 PHP 脚本提供压缩数据的情况。我在Java端压缩数据没问题,但是PHP好像解压不了。

这是Java端的相关代码片段:

  OutputStream o=response.getOutputStream();

GZIPOutputStream gz=new GZIPOutputStream(o);
gz.write(GridCoder.encode(rs,id, perPage, page).getBytes());
gz.close();
o.close();

PHP端:

$xml= gzuncompress($xml);

有人可以指出我正确的方向。

4

4 回答 4

11

我刚看到你的问题,很好奇。所以我做了我自己的测试用例。我将所有与 Servlet 相关的东西都排除在了问题之外,并编写了如下代码:

import java.io.*;
import java.util.zip.GZIPOutputStream;

public class GZIPTestcase {

    public static void main(String[] args) throws Throwable {
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(new File("/Users/malax/foo2.gz")));
        PrintWriter pw = new PrintWriter(gzipOutputStream);

        pw.println("All your base are belong to us!");
        pw.flush();
        pw.close();
    }
}

GNU gunzip 能够解压缩数据。然后我尝试用 PHP 解压缩它。它失败了,你得到了同样的错误。我进一步调查并发现了以下方法:

  • gzdecode()
  • gzinflate()

gzinflate 也不起作用,gzdecode 仅随 PHP6 一起提供,我还没有安装。也许你可以试试这个。(根据http://bugs.php.net/bug.php?id=22123这会起作用)

我怀疑问题出在 Java 方面,因为 GNU 的 gunzip 可以压缩数据,所以它必须是正确的。您可能想在 PHP 方面进行进一步调查。

.NET 和 PHP 存在一个相关问题,原始发帖人与您有相同的问题:PHP 可以解压缩使用 .NET GZipStream 类压缩的文件吗?. PHP 似乎也无法从与 GZIPOutputStream 等效的 .NET 中解压缩数据。

抱歉,我没有“解决方案”,但无论如何我可能已经为您指明了正确的方向。

编辑:我在 PHP Bugtracker 中找到了一个解释问题的条目: http ://bugs.php.net/bug.php?id=22967 似乎 gzuncompress 无法解压缩 GZIP 数据,其标题将生成为 GZIPOutputStream。如 Bugtracker 条目中所述,尝试裁剪标题。

于 2009-09-10T20:47:08.763 回答
6

尝试使用 DeflaterOutputStream 而不是 GZIPOutputStream

PHP 函数调用实现 DEFLATE 的 libzlib。Gzip 是完全不同的野兽。

将 PHP 函数命名为 gz XXX只会增加混乱。

于 2009-09-10T21:26:35.510 回答
3

我找到了一种修复它的方法,使用 Devon_C_Miller 和 Malax 的帖子作为指导。

java的代码:

   String body = "Lorem ipsum shizzle ma nizle";

   URL url = new URL("http://some.url/file.php?id=" + uid);
   URLConnection conn = url.openConnection();
   conn.setDoOutput(true);
   conn.setRequestProperty("Content-encoding", "deflate");
   conn.setRequestProperty("Content-type", "application/octet-stream");

   DeflaterOutputStream dos = new DeflaterOutputStream(conn.getOutputStream());

   dos.write(body.getBytes());
   dos.flush();
   dos.close();

PHP端:

   $content = http_get_request_body();

   $uncontent = gzuncompress($content);
于 2011-05-20T11:51:34.943 回答
1

“Java Deflater + PHP gzuncompress ”的组合对我有用。客户端:Android 4.1.1,服务器站点:php 5.3

对于谁正在寻找在某些情况下仅压缩部分请求正文的解决方案,例如我,使用 HTTP 表单发布一些参数和文件,以下是我在 Android 端使用的代码段:

    public static byte[] compressString(String data) throws IOException {
        byte[] compressed = null;
        byte[] byteData = data.getBytes();
        ByteArrayOutputStream bos = new ByteArrayOutputStream(byteData.length);
        Deflater compressor = new Deflater();
        compressor.setLevel(Deflater.BEST_COMPRESSION);
        compressor.setInput(byteData, 0, byteData.length);
        compressor.finish();

        // Compress the data
        final byte[] buf = new byte[1024];
        while (!compressor.finished()) {
            int count = compressor.deflate(buf);
            bos.write(buf, 0, count);
        }
        compressor.end();
        compressed = bos.toByteArray();
        bos.close();
        return compressed;
    }
于 2014-07-21T07:04:48.187 回答