无法使用mono进行压缩?

7
我正在尝试像这样在Mono中压缩一些数据:
public static string Save(FlightProgram program, bool compressed)
{
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter f = new BinaryFormatter();
        if (compressed)
        {
            using (DeflateStream gz = new DeflateStream(ms, CompressionMode.Compress))
            {
                f.Serialize(gz, program);
            }
        }
        else
        {
            f.Serialize(ms, program);
        }
        return Convert.ToBase64String(ms.ToArray()).Replace('/', '_');
    }
}

我只是得到了异常"CreateZStream",没有内部异常。这里发生了什么?

堆栈跟踪:

Could not save flight program: CreateZStream at   at (wrapper managed-to-native) System.IO.Compression.DeflateStream:CreateZStream (System.IO.Compression.CompressionMode,bool,System.IO.Compression.DeflateStream/UnmanagedReadOrWrite,intptr)
    at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, CompressionMode mode, Boolean leaveOpen, Boolean gzip) [0x00000] in <filename unknown>:0 
    at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, CompressionMode mode) [0x00000] in <filename unknown>:0 
    at KSPComputerModule.ProgramSerializer.Save (KSPComputer.FlightProgram program, Boolean compressed) [0x00000] in <filename unknown>:0 
    at KSPComputerModule.FPComputer.OnSave (.ConfigNode node) [0x00000] in <filename unknown>:0  (State: None)

1
我其实不知道Unity是如何工作的,但我猜他们会查看IL代码并重新编译/重新链接它。也许他们不完全支持System.IO.Compression(参见:http://forum.unity3d.com/threads/solved-binary-data-compression-with-deflatestream.31258/)。 - mbx
2个回答

6
当然这个问题已经和OP无关了,但我最终还是自己解决了。这是Mono for Windows部署中的一个bug。如果你从Mono/GtkSharp目录下删除MonoPosixHelper.dll文件,你会发现它突然就能正常工作了。使用进程监视器可以看到,现在它不再使用被编译错误的MonoPosixHelper.dll,而是使用正确编译的libMonoPosixHelper.dll。
所以,要永久解决问题,要么删除所有的MonoPosixHelper.dll文件,让它使用libMonoPosixHelper.dll,要么最好使用dllmap,并添加:
 <dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dll" os="windows" />

将其添加到以下位置之一:C:\ Program Files(x86)\ Mono \ lib \ mono \ gac \ System \ 4.0.0.0__b77a5c561934e089 \ System.dll.config(如果不存在,请创建),或全局 Mono 配置 C:\ Program Files(x86)\ Mono \ etc \ mono \ config


5

我已经亲自测试过,结果出现了DllNotFoundException错误:

System.DllNotFoundException: MonoPosixHelper
  at (wrapper managed-to-native) System.IO.Compression.DeflateStream:CreateZStream (System.IO.Compression.CompressionMode,bool,System.IO.Compression.DeflateStream/UnmanagedReadOrWrite,intptr)
  at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, CompressionMode mode, Boolean leaveOpen, Boolean gzip) [0x00000] in <filename unknown>:0 
  at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, CompressionMode mode) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.IO.Compression.DeflateStream:.ctor (System.IO.Stream,System.IO.Compression.CompressionMode)

问题似乎出在CreateZStream函数上,它是一个外部方法,应该在MonoPosixHelper.dll中定义。

CreateZStream被声明为

[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateZStream(CompressionMode compress, bool gzip, DeflateStream.UnmanagedReadOrWrite feeder, IntPtr data);

然而,文件“MonoPosixHelper.dll”不存在。存在一个名为libMonoPosixHelper.dylib的文件,其中实现了CreateZStream的入口点,但这是适用于Mac的库。

就我个人而言,在Unity中,大多数压缩代码/库都给我带来了糟糕的体验,因为大多数实现只是将本地代码库封装起来。根据兼容性页面的说明,该类得到了支持,但看起来只实现了托管部分。也有一篇文章在确认这一点

我已经成功地在许多项目中使用SharpZipLib库。它是一个纯管理库,没有任何本地代码依赖。我在独立、Web、Android和iOS版本上使用过这个库,没有遇到任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接