在C#中压缩字符串并在python中解压缩

时间:2013-07-11 12:49:49

标签: c# python django compression gzip

我正在尝试在C#(。net 4)中压缩客户端程序上的大字符串,并使用PUT请求将其发送到服务器(django,python 2.7)。 理想情况下,我想在两端使用标准库,所以我尝试使用gzip。

我的C#代码是:

public static string Compress(string s) {
    var bytes = Encoding.Unicode.GetBytes(s);
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
            msi.CopyTo(gs);
        }
        return Convert.ToBase64String(mso.ToArray());
    }
}

python代码是:

s = base64.standard_b64decode(request)
buff = cStringIO.StringIO(s)

with gzip.GzipFile(fileobj=buff) as gz:
    decompressed_data = gz.read()

它几乎正常工作,但输出是:{▯“▯c▯h▯a▯n▯g▯e▯d▯”when}当应该{“改变”},即每隔一个字母都是奇怪的东西。 如果我通过执行decompressed_data [:: 2]取出所有其他角色,那么它可以工作,但它有点像黑客,显然还有其他错误。

我想知道我是否需要对PUT请求进行base64编码?这只是POST的必要吗?

2 个答案:

答案 0 :(得分:4)

我认为主要问题可能是C#使用UTF-16编码的字符串。这可能会产生类似于您的问题。与任何其他编码问题一样,我们可能需要一点运气,但我想你可以通过这样做来解决这个问题:

decompressed_data = gz.read().decode('utf-16')

在那里,decompressed_data应为Unicode,您可以将其视为进一步的工作。

更新:这对我有用:

C Sharp

static void Main(string[] args)
    {
        FileStream f = new FileStream("test", FileMode.CreateNew);
        using (StreamWriter w = new StreamWriter(f))
        {
            w.Write(Compress("hello"));
        }
    }
    public static string Compress(string s)
    {
        var bytes = Encoding.Unicode.GetBytes(s);
        using (var msi = new MemoryStream(bytes))
        using (var mso = new MemoryStream())
        {
            using (var gs = new GZipStream(mso, CompressionMode.Compress))
            {
                msi.CopyTo(gs);
            }
            return Convert.ToBase64String(mso.ToArray());
        }
    }

的Python

import base64
import cStringIO
import gzip

f = open('test','rb')
s = base64.standard_b64decode(f.read())
buff = cStringIO.StringIO(s)

with gzip.GzipFile(fileobj=buff) as gz:
    decompressed_data = gz.read()
    print decompressed_data.decode('utf-16')

没有decode('utf-16)它在控制台中打印:

>>>h e l l o

用它做得很好:

>>>hello
祝你好运,希望这会有所帮助!

答案 1 :(得分:2)

  

它几乎正常工作,但输出是:{▯“▯c▯h▯a▯n▯g▯e▯d▯”▯}应该{“更改”}

那是因为你使用Encoding.Unicode将字符串转换为字母开头。

如果你能告诉Python使用哪种编码,你可以这样做 - 否则你需要在C#端使用与Python期望的匹配的编码。

如果可以双方指定,我建议使用UTF-8而不是UTF-16。即使你正在压缩,使数据的一半大小(在很多情况下)开始时也不会有害:)

我也有点怀疑这一行:

buff = cStringIO.StringIO(s)

s实际上不是文本数据 - 它是压缩的二进制数据,应该这样对待。这可能没问题 - 只是值得检查是否有更好的方法。