4

我正在尝试在 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());
    }
}

蟒蛇代码是:

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▯"▯} 当它应该是 {"changed"} 时,即每个其他字母都很奇怪。如果我通过 decompressed_data[::2] 取出所有其他字符,那么它可以工作,但它有点像 hack,显然还有其他问题。

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

4

2 回答 2

4

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

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

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

更新:这对我有用:

C夏普

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

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

于 2013-07-11T12:56:58.210 回答
2

它几乎可以工作,但输出是: {▯"▯c▯h▯a▯n▯g▯e▯d▯"▯} 当它应该是 {"changed"}

那是因为您正在使用Encoding.Unicode将字符串转换为字节开始。

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

如果你可以在两边都指定它,我建议使用 UTF-8 而不是 UTF-16。即使您正在压缩,将数据大小减半(在许多情况下)开始时也不会受到伤害:)

我也有点怀疑这条线:

buff = cStringIO.StringIO(s)

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

于 2013-07-11T12:54:28.480 回答