2014-10-30 9 views
7

Ich versuche, einige Daten in mono so zu komprimieren:Kann nicht mit Mono komprimiert werden?

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('/', '_'); 
    } 
} 

Ich bin einfach die Ausnahme „CreateZStream“ bekommen. Keine innere Ausnahme. Was ist denn hier los ?

Stacktrace:

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

Ich weiß eigentlich nicht, wie Unity funktioniert, aber ich schätze, sie schauen sich den IL-Code an und kompilieren ihn erneut. Möglicherweise unterstützen sie die System.IO.Compression nicht vollständig (siehe: http://forum.unity3d.com/threads/solved-binary-data-compression-with-defatestream.31258/) – mbx

Antwort

4

Ich habe es selbst getestet und ich bekomme eine 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) 

Der Grund scheint die CreateZStream Funktion zu sein, die eine externe Methode ist, die im Inneren definiert werden soll die MonoPosixHelper.dll.

CreateZStream als

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

jedoch die Datei "MonoPosixHelper.dll" existiert nicht. Es gibt eine libMonoPosixHelper.dylib, die einen Einstiegspunkt für CreateZStream zu implementieren scheint, aber das ist eine Bibliothek für Mac.

Ich persönlich hatte schlechte Erfahrungen mit den meisten Komprimierungscode/Bibliotheken in Unity, da die meisten Implementierungen einfach eine native Code-Bibliothek umschließen. Laut der compatibility page wird die Klasse unterstützt, jedoch sieht es nur nach der managed part is implemented aus. This one scheint dies auch zu bestätigen.

Ich habe die SharpZipLib Bibliothek in vielen Projekten erfolgreich verwendet. Es ist eine reine verwaltete Bibliothek ohne systemeigene Codeabhängigkeiten. Ich habe diese Bibliothek in Standalone-, Web-, Android- und iOS-Builds ohne Probleme verwendet.

6

Sicherlich nicht mehr relevant für das OP ... aber ich habe es endlich geschafft, das selbst zu lösen. Es ist ein Fehler in der Mono für Windows-Bereitstellung. Wenn Sie MonoPosixHelper.dll Dateien aus Mono/GtkSharp-Verzeichnissen löschen, werden Sie plötzlich feststellen, dass es funktioniert. Running Process Monitor, können Sie sehen, dass anstelle für die mal kompiliert MonoPosixHelper.dll geht es jetzt für libMonoPosixHelper.dll ... die korrekt kompiliert wird.

So lösen dauerhaft entweder löschen Sie alle MonoPosixHelper.dll Dateien, so dass es libMonoPosixHelper.dll verwendet ... oder vorzugsweise eine dllmap verwenden,

<dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dll" os="windows" /> 

entweder C:\Program Files (x86)\Mono\lib\mono\gac\System\4.0.0.0__b77a5c561934e089\System.dll.config Hinzufügen (erstellen, wenn es doesn 't existiert bereits) oder zur globalen Mono-Konfiguration unter C:\Program Files (x86)\Mono\etc\mono\config