omega
omega

Reputation: 43833

Zlib decompression in java not working

I am compressing a string in PHP 5.4.4-14+deb7u7 using

$cdat = gzcompress($dat, 9);

http://php.net/manual/en/function.gzcompress.php

Then in android/java I want to decompress it, from here: Android: decompress string that was compressed with PHP gzcompress()

I am using:

public static String unzipString(String zippedText) {
    String unzipped = null;
    try {
        byte[] zbytes = zippedText.getBytes("ISO-8859-1");
        // Add extra byte to array when Inflater is set to true
        byte[] input = new byte[zbytes.length + 1];
        System.arraycopy(zbytes, 0, input, 0, zbytes.length);
        input[zbytes.length] = 0;
        ByteArrayInputStream bin = new ByteArrayInputStream(input);
        InflaterInputStream in = new InflaterInputStream(bin);
        ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
        int b;
        while ((b = in.read()) != -1) {
            bout.write(b); 
        }
        bout.close();
        unzipped = bout.toString();
    } catch (IOException e) { 
    }
    return unzipped;
 }

But when I tried it, it decompressed into an empty string, when the downloaded compressed string in android was really long.

The downloaded string was like

x�͜{o�8�a`�= �!�����[��K!(6c�E�$��]�)�HF��F\!����ə���L�LNnH]Lj٬T��M���f�'�u#�*_�7'�S^�w��*kڼn�Yޚ�I��e$.1C��~�ݟ��F�A�_Mv_�R͋��ܴ�Z^L���sU?A���?�׮�ZVmֽ6��>�B��C�M�*����^�sٸ�j����������?�"_�j�ܣY�E���h0�g��w[=&�D �oht=>�l�?��Po";`.�e�E�E��[���������sq��0���i]��������zUL�O{П��ժ�k��b�.&7��-d1_��ۣ�狝�y���=F��K!�rC�{�$����c�&9ޣH���n�x�

Does anyone know what the problem is?

Thanks.

public static Pair<String,Integer> GetHTTPResponse(String url, List<NameValuePair> urlparameters) {
    String responseVal = null;
    int responseCode = 0;

    try {
        HttpParams httpParameters = new BasicHttpParams();
        int timeoutConnection = TIMEOUT_SECONDS * 1000;
        HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        int timeoutSocket = TIMEOUT_SECONDS * 1000;
        HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

        HttpClient client = new DefaultHttpClient(httpParameters);
        HttpPost httppost = new HttpPost(url);

        httppost.setEntity(new UrlEncodedFormEntity(urlparameters));
        HttpResponse response = client.execute(httppost);
        responseCode = response.getStatusLine().getStatusCode();    

        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

        responseVal = Common.GetStringFromBufferedReader(rd);

        Log.d("SERVER", responseVal);
    }
    catch (Exception e) {
        responseCode = 0;
    }

    if (responseVal != null) {
        responseVal = Common.unzipString(responseVal);
    }

    return new Pair<String, Integer>(responseVal, responseCode);
}

Upvotes: 1

Views: 1367

Answers (1)

Elliott Frisch
Elliott Frisch

Reputation: 201439

You can't use

BufferedReader rd = 
    new BufferedReader(new InputStreamReader(
        response.getEntity().getContent()));
responseVal = Common.GetStringFromBufferedReader(rd);

As InputStreamReader's Javadoc notes,

An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset.

Instead, you could use HttpEntity.writeTo(OutputStream) and a ByteArrayOutputStream like

ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.getEntity().writeTo(baos);
byte[] content = baos.toByteArray();

Then you can directly pass the content to your function in that byte[], and never silently swallow an Exception.

public static String unzipString(byte[] zbytes) {
    String charsetName = "ISO-8859-1";
    String unzipped = null;
    try {
        // Add extra byte to array when Inflater is set to true
        byte[] input = new byte[zbytes.length + 1];
        System.arraycopy(zbytes, 0, input, 0, zbytes.length);
        input[zbytes.length] = 0;
        ByteArrayInputStream bin = new ByteArrayInputStream(input);
        InflaterInputStream in = new InflaterInputStream(bin);
        ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
        int b;
        while ((b = in.read()) != -1) {
            bout.write(b); 
        }
        bout.close();
        unzipped = bout.toString(charsetName);
    } catch (IOException e) { 
        e.printStackTrace();
    }
    return unzipped;
 }

Upvotes: 1

Related Questions