【问题标题】:Gzip compression and http post from python to javaGzip 压缩和从 python 到 java 的 http post
【发布时间】:2016-08-22 10:55:21
【问题描述】:

我想将一个 gzip 压缩数据从 python 发布到 java,我想将它作为 BLOB 存储在数据库中。然后我想用gzip解压缩java中的那个BLOB。所以我想知道如何在 python 中发布 BLOB 以及如何在 java 中读取 BLOB。我在下面给出了我的 python 和 java 代码。在我的代码中,我 gzip 在 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 中读取并打印该文件中的压缩数据,我会得到 ​​p>

[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();
}
}

【问题讨论】:

    标签: java python http-post gzip compression


    【解决方案1】:

    您不能直接将压缩数据读取到字符串。您在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不能转换成字符串,所以当你用bytesBefore新建字符串时,str存储在内存中的字节是bytesAfter,这会将-1和-2改为-17- 65 -67 -17 -65 -67 .

    其实GZIPInputStream可以用FileInputStream构建,不需要先获取字节。只需使用BufferedReader读取GZIPInputStream,它是用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
    

    【讨论】:

    • 此解决方案运行良好。我改变了我的代码,如下所示, File file = new File("comp_dump");字节[] bs = 新字节[(int)file.length()]; FileInputStream fis = new FileInputStream(file); int len = fis.read(bs);我会将字节数组 bs 作为 GZIPInputStream 的输入来解压缩。但在此我们将文件作为输入。我想将压缩数据发布到 java。然后我们必须在 java 端读取这些数据作为字节。那么如何在java中将发布的压缩数据读取为字节,并且可以将其存储为mysql中的什么类型。可以在mysql中存储为BLOB吗?
    • 是的,BLOB 没问题。使用 GZIPInputStream 和 BLOB 的字节作为输入。
    【解决方案2】:

    你检查过这个:gzip a file in Python 吗?

    我的猜测是你的字符串

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

    可能导致整个过程出现一些问题...

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

    【讨论】:

    • 没有。它抛出相同的异常
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2016-04-11
    • 2015-10-21
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多