用Python压缩和用DecompressC#解压的最简单方法(反之亦然)

用Python压缩和用DecompressC#解压的最简单方法(反之亦然),c#,.net,python,mono,compression,C#,.net,Python,Mono,Compression,我有一个带有基于单声道的C#客户端和Python服务器的程序,它们通过TCP/IP套接字进行通信。消息主要使用二进制格式,但每条消息的最大部分通常嵌入UTF-8字符串(英语)。每条消息通常较短(小于100字节),但有些消息可能较长(高达64K)。大量数据被交换,我想通过在传输数据时压缩数据来减少消息大小和带宽使用 我最初的研究没有发现任何明显兼容两个标准库的东西。Python有一个库,但我不能使用C#或GZipStream(因为它们需要一个我没有的外部DLL),而且它似乎不能与SharpZipL

我有一个带有基于单声道的C#客户端和Python服务器的程序,它们通过TCP/IP套接字进行通信。消息主要使用二进制格式,但每条消息的最大部分通常嵌入UTF-8字符串(英语)。每条消息通常较短(小于100字节),但有些消息可能较长(高达64K)。大量数据被交换,我想通过在传输数据时压缩数据来减少消息大小和带宽使用

我最初的研究没有发现任何明显兼容两个标准库的东西。Python有一个库,但我不能使用C#或GZipStream(因为它们需要一个我没有的外部DLL),而且它似乎不能与SharpZipLib的ZipoutStream一起工作(给出“error-3-error header”响应)。(那些不使用Mono的人可能会更幸运——见下面邓肯的答案。)

我很想听听通过这种通信链路实现压缩的简单方法,要记住,任何可能在一种语言中易于实现的解决方案都需要在另一种语言中有一个等价物。我会接受一种专门针对UTF-8字符串而不是二进制消息的解决方案,尽管首选是压缩整个字节流

理想情况下,我希望尽量减少外部依赖性,但我意识到这可能不现实


更新:尝试使用SharpZipLib后,在Python解码端多次遇到错误,我真的可以对已知有效的代码提出具体的建议,而不仅仅是对一种或另一种语言的压缩库的建议。

我过去使用过zlib for.net,还有一些库包装本机zlib库以提供托管解决方案。我需要做一些和你现在做的相似的事情。对于较小的传输,我会直接在内存中进行压缩,然后压缩到一个文件,然后从url下载该文件,对于更大的文件,我会从文件中解压缩。

您写道:

类似地,两个标准库都提供gzip压缩,但Python不提供 希望在这种情况下使用文件,这是不实际的

事实并非如此。Python的
gzip.GZipFile()
类采用
filename
fileobj
。如果要使用字符串,只需使用
StringIO
对象作为
fileobj

from gzip import GzipFile
from StringIO import StringIO
sio = StringIO()
with GzipFile(fileobj=sio, mode='wb') as gzip:
    gzip.write('uncompressed data')
compressed = sio.getvalue()

你好像在开尼克斯系统。如果是这种情况,并且所有其他方法都失败了,那么您可以简单地使用系统库(Mono.Unix.Native),而不必担心找到合适的.Net库

SharpZipLib和Python库中的BZip2对我很有用。以下是我测试的内容和方法:

首先,C#计划(参考SharpZipLib):

接下来,运行C#程序。在那之后:

$ python ctest.py
Line no 0.
Line no 1.
Line no 2.
Line no 3.
Line no 4.
Line no 5.
Line no 6.
Line no 7.
Line no 8.
Line no 9.

我认为它也可以反过来工作。

SharpZip有与zlib兼容的实现—InflaterInputStream和DeflaterOutputStream这是一个很好的观点,值得了解。不幸的是,我不能在C#端使用gzip,所以我正在寻找替代方案。不,不幸的是,我需要双方都是平台独立的——这并不能解决Python端的问题。这对我很有效。C#中的using子句非常关键——没有它,压缩就不会发生。我猜压缩库需要先处理相关流,然后才能压缩数据并将其刷新到底层流中。
from bz2 import BZ2File
import sys

f = BZ2File("/home/konrad/output.bin")
for line in f.readlines():
    sys.stdout.write(line)
$ python ctest.py
Line no 0.
Line no 1.
Line no 2.
Line no 3.
Line no 4.
Line no 5.
Line no 6.
Line no 7.
Line no 8.
Line no 9.