当前位置: 首页 > 知识库问答 >
问题:

从python到java的Gzip压缩和http post

蔚丰
2023-03-14

我想通过http将gzip压缩数据从python发布到java,并将其作为BLOBhtml" target="_blank">存储在数据库中。然后我想用java解压这个BLOB。所以我想知道如何在python中发布BLOB,以及如何在java中读取BLOB。下面是我的python和java代码。在我的代码中,我用python压缩一个字符串,并将压缩后的数据存储在一个文件中。然后我用java读取该文件,并使用GZIPInputStream对其进行解压缩。但我得到了以下例外。

java.io.IOException: Not in GZIP format
    at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:154)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:75)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:85)
    at GZipFile.gunzipIt(GZipFile.java:60)
    at GZipFile.main(GZipFile.java:43)

如果我用python打印压缩数据的字节数组

[31, 139, 8, 0, 254, 213, 186, 87, 2, 255, 203, 72, 205, 201, 201, 231, 229, 42, 207, 47, 202, 73, 1, 0, 66, 102, 86, 48, 12, 0, 0, 0]

如果我用java读取并打印该文件中的压缩数据,我会得到

[31, -17, -65, -67, 8, 0, -17, -65, -67, -42, -70, 87, 2, -17, -65, -67, -17, -65, -67, 72, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, 42, -17, -65, -67, 47, -17, -65, -67, 73, 1, 0, 66, 102, 86, 48, 12, 0, 0, 0]

你可以看到有区别。如果我将python中打印的字节数组作为java代码的输入,它就可以正常工作。因此,请帮助我了解如何用python发布blob(压缩数据),以及如何用java读取压缩数据以对其进行解压缩。

这是python中的压缩代码:

import StringIO  
import gzip  
import base64  
import os  


m='hello'+'\r\n'+'world'  

out = StringIO.StringIO()  
with gzip.GzipFile(fileobj=out, mode="wb") as f:  

    f.write(m.encode('utf-8'))
print list(array.array('B',out.getvalue())[:])
f=open('comp_dump','wb')  
f.write(out.getvalue())  
f.close()

这是java中的解压缩代码:

//$Id$

import java.io.*;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.util.zip.GZIPInputStream;  
import javax.xml.bind.DatatypeConverter;  
import java.util.Arrays;

public class GZipFile
{


public static String readCompressedData()throws Exception
{
        String compressedStr ="";
        String nextLine;
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("comp_dump")));
        try
        {
                while((nextLine=reader.readLine())!=null)
                {
                        compressedStr += nextLine;
                }
        }
        finally
        {
                reader.close();
        }
        return compressedStr;
}

public static void main( String[] args ) throws Exception
{
        GZipFile gZip = new GZipFile();
        byte[] contentInBytes = readCompressedData().getBytes("UTF-8");

        System.out.println(Arrays.toString(contentInBytes));
        String decomp = gZip.gunzipIt(contentInBytes);
        System.out.println(decomp);
}

/**
 * GunZip it
 */
public static String gunzipIt(final byte[] compressed){

        byte[] buffer = new byte[1024];
        StringBuilder decomp = new StringBuilder() ;

        try{

                GZIPInputStream gzis = new GZIPInputStream(new ByteArrayInputStream(compressed));

                int len;
                while ((len = gzis.read(buffer)) > 0) {

                        decomp.append(new String(buffer, 0, len));

                }

                gzis.close();

        }catch(IOException ex){
                ex.printStackTrace();
        }
        return decomp.toString();
}
}

共有2个答案

拓拔弘扬
2023-03-14

你在Python中检查过这个:gzip文件了吗?

我猜你的琴弦

m='hello'+'\r\n'+'world' 

可能会给整个过程带来一些问题。。。

您是否考虑过将其替换为m=“hello\r\nworld”,改为使用双引号?

荀子轩
2023-03-14

不能直接将压缩数据读取为字符串。在readCompressedData方法中,您所做的是将压缩数据读取为文本(这会导致错误的字符串),然后获取其字节(在方法main中)。执行此操作后,contentInBytes实际上不是存储在文件中的字节。

当您尝试使用无法转换为String的字节创建字符串时,表示字符串的字节是不同的。

例如:

        byte bytesBefore[] = {-1,-2,65,76,79,80};
        try {
            String str = new String(bytesBefore);
            byte bytesAfter[] = str.getBytes();
            System.out.println("str is " + str);
            System.out.println("after");
            for(Byte b : bytesAfter){
                System.out.print(" " + b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

输出:

str is ��ALOP
after
 -17 -65 -67 -17 -65 -67 65 76 79 80

因为这里的字节-1和-2不能转换成字符串,所以当你用字节before新建字符串时,存储在str内存中的字节是字节before,这将-1和-2更改为-17-65-67-17-65-67。

实际上,gzip输入流可以使用FileInputStream构建,无需先获取字节。只需使用BufferedReader读取gzip输入流,它是用FileInputStream构建的。

有一个解决办法:

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

public class GZipFile {
    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                new GZIPInputStream(new FileInputStream(
                        "comp_dump")), "UTF-8"));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\r\n");
        }
        System.out.println(sb.toString());
    }
}

输出:

hello
world
 类似资料:
  • 使用的字符串: string='hello'+'\r\n'+'world' Java中的预期输出: out.getValue() f.write(Base64.b64Encode(Out.getValue())) F.Close() ByteArrayInputStream(压缩)); InputStreamReader(gis,“UTF-8”));

  • 问题内容: 我是新手。但是我正在玩REST Api。我无法从json.marshal中获得与json.Encoder相同的行为,我有两个函数 我想使用此功能gzip我的答复: 但是此函数返回以下内容: 这是go函数: 但是当我取消评论时: 它工作正常。 问题答案: 您需要先刷新或关闭gzip编写器,然后再访问基础字节,例如 否则,不会收集gzip编写器中已缓冲但尚未写到最终流中的内容。

  • 问题内容: 我有一个内存和磁盘受限的环境,我需要解压缩以字符串为基础的块(通过xmlrpc二进制传输)发送给我的gzip文件的内容。但是,使用zlib.decompress()或zlib.decompressobj()/ decompress()都可以在gzip标头上使用barf。我已经尝试过偏移gzip标头(在此处记录),但是仍然没有避免使用barf。gzip库本身似乎仅支持从文件解压缩。 以下

  • 问题内容: 我正在使用php的功能来执行HTTP请求。为了节省带宽,我决定使用添加标题。 显然,输出一个gzip编码的字符串,所以我用来解码该编码的字符串,但是将作为参数传递的数据出错。 我知道还有另一个功能可以解压缩压缩后的数据,但是它不包含在我的PHP版本中(也许仅在SVN上可用)。 我知道cUrl可以即时解码gzip流(没有任何问题),但是有人建议我使用它而不是cUrl。 您是否知道以其他方

  • 我想在java中解压缩一个字符串,它在Python中被gzip压缩。 这是Java中的解压缩代码: }