gt6*_*07a 10 c# python compression python.net brotli
所以我想利用Brotli,但我不熟悉Python和C++.
我知道有人将其编译成Windows .exe.但是如何将其包装到DLL或.NET应用程序可以引用的内容中呢?我知道有IronPython,我是否只是将所有源文件引入IronPython项目并编写调用Brotli API的.NET适配器并公开它们?但实际上,我甚至不确定Brotli API是Python还是C++.
看着tools/bro.cc,它看起来像"进入"方法在定义encode.c和decode.c为BrotliCompress(),BrotliDecompressBuffer(),BrotliDecompressStream()的方法.所以我想可以从C++类编译DLL.
Sim*_*ier 13
为了避免使用Python,我在https://github.com/smourier/brotli中分享了原始的brotli源代码,并创建了一个可以与.NET一起使用的Windows DLL版本.我添加了一个目录,其中包含一个带有两个项目的"WinBrotli"Visual Studio 2015解决方案:
要重用Winbrotli DLL,只需复制WinBrotli.x64.dll和WinBrotli.x86.dll(您可以在WinBrotli/binaries文件夹中找到已构建的发行版本),而不是 .NET应用程序,并将BrotliCompression.cs文件合并到C#中项目(或将其移植到VB或其他语言,如果C#不是您最喜欢的语言).互操作代码将自动选择与当前进程的位数(X86或X64)相对应的正确DLL.
完成后,使用它非常简单(输入和输出可以是文件路径或标准.NET Streams):
// compress
BrotliCompression.Compress(input, output);
// decompress
BrotliCompression.Decompress(input, output);
Run Code Online (Sandbox Code Playgroud)
要创建WinBrotli,这就是我所做的(对于其他想要使用其他Visual Studio版本的人)
我将通过从.NET代码调用python本机库来展示一种方法.你需要什么:
你需要从源代码编译brotli.希望这很容易.首先为Python 2.7安装Microsoft Visual C++编译器.然后克隆brotli存储库git clone https://github.com/google/brotli.git并使用编译python setup.py build_ext.完成后,在build\lib.win32-2.7目录中你会找到brotli.pyd文件.这是python c ++模块 - 我们稍后会需要它.
您需要下载pythonnet二进制文件或从源代码编译它.我们在这里使用pythonnet的原因,而不是Iron Python,因为Iron Python不支持本机(C\C++)python模块,这就是我们在这里需要的.所以,要从源代码编译,git clone https://github.com/pythonnet/pythonnet.git然后通过编译来克隆python setup.py build.结果你会得到Python.Runtime.dll(在build\lib.win32-2.7目录中),这是我们需要的.
完成所有操作后,创建控制台项目,引用Python.Runtime.dll,然后:
public static void Main()
{
PythonEngine.Initialize();
var gs = PythonEngine.AcquireLock();
try {
// import brotli module
dynamic brotli = PythonEngine.ImportModule(@"brotli");
// this is a string we will compress
string original = "XXXXXXXXXXYYYYYYYYYY";
// compress and interpret as byte array. This array you can save to file for example
var compressed = (byte[]) brotli.compress(original);
// little trick to pass byte array as python string
dynamic base64Encoded = new PyString(Convert.ToBase64String(compressed));
// decompress and interpret as string
var decompressed = (string) brotli.decompress(base64Encoded.decode("base64"));
// works
Debug.Assert(decompressed == original);
}
finally {
PythonEngine.ReleaseLock(gs);
PythonEngine.Shutdown();
}
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
然后构建它并将你在上面的brotli.pyc与.exe文件放在同一目录中.在完成所有操作之后,您将能够从.NET代码进行压缩和解压缩,如上所示.
您可以使用 Brotli.NET,它提供完整的流支持。
要将流压缩为 brotli 数据:
public Byte[] Encode(Byte[] input)
{
Byte[] output = null;
using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
using (BrotliStream bs = new BrotliStream(msOutput, System.IO.Compression.CompressionMode.Compress))
{
bs.SetQuality(11);
bs.SetWindow(22);
msInput.CopyTo(bs);
bs.Close();
output = msOutput.ToArray();
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
要解压缩 brotli 流:
public Byte[] Decode(Byte[] input)
{
using (System.IO.MemoryStream msInput = new System.IO.MemoryStream(input))
using (BrotliStream bs = new BrotliStream(msInput, System.IO.Compression.CompressionMode.Decompress))
using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream())
{
bs.CopyTo(msOutput);
msOutput.Seek(0, System.IO.SeekOrigin.Begin);
output = msOutput.ToArray();
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
要在 Web 应用程序中支持动态压缩,请在 Global.asax.cs 中添加如下代码:
protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
var app = Context.ApplicationInstance;
String acceptEncodings = app.Request.Headers.Get("Accept-Encoding");
if (!String.IsNullOrEmpty(acceptEncodings))
{
System.IO.Stream baseStream = app.Response.Filter;
acceptEncodings = acceptEncodings.ToLower();
if (acceptEncodings.Contains("br") || acceptEncodings.Contains("brotli"))
{
app.Response.Filter = new Brotli.BrotliStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "br");
}
else
if (acceptEncodings.Contains("deflate"))
{
app.Response.Filter = new System.IO.Compression.DeflateStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "deflate");
}
else if (acceptEncodings.Contains("gzip"))
{
app.Response.Filter = new System.IO.Compression.GZipStream(baseStream, System.IO.Compression.CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2956 次 |
| 最近记录: |