2014-10-30 7 views
7

sto cercando di comprimere alcuni dati in mono come questo:Impossibile comprimere con 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('/', '_'); 
    } 
} 

che sto semplicemente ottenere l'eccezione "CreateZStream". Nessuna eccezione interiore Cosa sta succedendo qui ?

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

In realtà non so come funziona Unity, ma suppongo che guardino il codice IL e ricompilino/ricollegalo. Forse non supportano completamente System.IO.Compression (vedi: http://forum.unity3d.com/threads/solved-binary-data-compression-with-deflatestream.31258/) – mbx

risposta

4

ho provato io stesso e ho un 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) 

Il motivo sembra essere la funzione di CreateZStream che è un metodo esterno che deve essere definita all'interno di il MonoPosixHelper.dll.

CreateZStream è dichiarato come

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

Tuttavia il file "MonoPosixHelper.dll" non esiste. C'è un libMonoPosixHelper.dylib che sembra implementare un entry point per CreateZStream, tuttavia questa è una libreria per mac.

Personalmente ho avuto brutte esperienze con la maggior parte dei codici/librerie di compressione in Unity poiché la maggior parte delle implementazioni include semplicemente una libreria di codice nativa. Secondo lo compatibility page la classe è supportata, tuttavia sembra solo lo managed part is implemented. Anche lo This one sembra verificarlo.

Ho utilizzato con successo la libreria SharpZipLib in molti progetti. È una libreria gestita allo stato puro senza dipendenze del codice nativo. Ho usato questa libreria in build standalone, web, android e iOS senza problemi.

6

Sicuramente non più pertinente all'OP più ... ma alla fine sono riuscito a risolverlo da solo. È un bug nella distribuzione di Mono per Windows. Se elimini i file MonoPosixHelper.dll dalle directory Mono/GtkSharp, troverai improvvisamente che funziona. In esecuzione Process Monitor, è possibile vedere che invece di andare per il mal-compilato MonoPosixHelper.dll, ora va per libMonoPosixHelper.dll ... che è compilato correttamente.

Così, per risolvere in modo permanente, eliminare tutti i file in modo che utilizza MonoPosixHelper.dll libMonoPosixHelper.dll ... o, preferibilmente, utilizzare un dllmap, aggiungendo

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

a uno C:\Program Files (x86)\Mono\lib\mono\gac\System\4.0.0.0__b77a5c561934e089\System.dll.config (creare se doesn esiste già) o alla Mono config globale a C:\Program Files (x86)\Mono\etc\mono\config