我正在尝试在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的必要吗?
答案 0 :(得分:4)
我认为主要问题可能是C#使用UTF-16
编码的字符串。这可能会产生类似于您的问题。与任何其他编码问题一样,我们可能需要一点运气,但我想你可以通过这样做来解决这个问题:
decompressed_data = gz.read().decode('utf-16')
在那里,decompressed_data应为Unicode
,您可以将其视为进一步的工作。
更新:这对我有用:
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());
}
}
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
实际上不是文本数据 - 它是压缩的二进制数据,应该这样对待。这可能没问题 - 只是值得检查是否有更好的方法。