2012-02-23 54 views
0

我是C#的新手,我正在編寫一個簡單的Web服務。它將zip文件解壓到文件系統中。在C#代碼:在C中解壓縮數據#

[WebMethod] 
public String SetZip(string device_id, string file) 
{ 
    if (device_id == null || device_id.Length == 0) 
    { 
     return "10;no auth data"; 
    } 

    StringBuilder output = new StringBuilder(); 

    if (direcory == null) 
    { 
     return output.ToString(); 
    } 

    string dirname = "c:\\temp\\" + direcory + "\\"; 

    if (!System.IO.Directory.Exists(dirname)) 
    { 
     System.IO.Directory.CreateDirectory(dirname); 
    } 

    string filename = dirname + "file1.txt"; 

    string text = UnZipStr(Convert.FromBase64String(file)); 

    File.WriteAllText(filename, text); 

    output.AppendLine("0;done"); 

    return output.ToString(); 
} 

public static string UnZipStr(byte[] input) 
{ 
    using (MemoryStream memstream = new MemoryStream()) 
    { 
     using (MemoryStream inputStream = new MemoryStream(input)) 
     { 
      using (DeflateStream gzip = 
       new DeflateStream(inputStream, CompressionMode.Decompress)) 
      { 
       using (StreamReader reader = 
        new StreamReader(gzip, System.Text.Encoding.UTF8)) 
       { 
        return reader.ReadToEnd(); 
       } 
      } 
     } 
    } 
} 

和發送從Java代碼zip數據:

void callService(byte[] xmlData) { 
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
    request.addProperty("device_id", AGENT); 

    Deflater deflater = new Deflater(); 
    deflater.setInput(xmlData); 
    deflater.finish(); 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    byte[] buf = new byte[1024]; 
    while (!deflater.finished()) { 
     int byteCount = deflater.deflate(buf); 
     baos.write(buf, 0, byteCount); 
    } 
    deflater.end(); 

    byte[] compressedBytes = baos.toByteArray(); 

    request.addPropertyIfValue("file", org.kobjects.base64.Base64.encode(compressedBytes));...} 

在C#代碼的StreamReader

SoapFault - faultcode: 'soap:Server' faultstring:  'System.Web.Services.Protocols.SoapException: ---> InvalidDataException: Block length does not correspond to the complement. 
System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block) 
System.IO.Compression.Inflater.Decode() 
System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length) 
System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count) 
System.IO.StreamReader.ReadBuffer() 
System.IO.StreamReader.ReadToEnd() 
Service.UnZipStr(Byte[] input) в c:\inetpub\wwwroot\WebSite\App_Code\Service.cs: at 94 
Service.SetZip(String device_id, String file) в c:\inetpub\wwwroot\WebSite\App_Code \Service.cs: at 73 

我在做什麼讀取數據時,我有例外錯誤?

+0

你試過用'GZipStream'而不是'DeflateStream'解壓嗎? – 2012-02-23 13:10:13

+0

是的,還有其他例外:「GZip頭部無效的幻數,傳輸必須進入GZip流。」 – user1228323 2012-02-23 13:14:07

+0

+1'的問題。蓋伊是一個新手。 – 2012-02-23 16:01:40

回答

0

編輯:我一直在挖掘,有一種方法可以從Java生成DEFLATE格式數據,C#可以識別:您必須使用Deflater(int,boolean)構造函數。因此,改變你的Java代碼:

Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true); 
deflater.setInput(xmlData); 
deflater.finish(); 

的原因是,默認情況下deflater發出ZLIB頭和校驗,其中C#DeflateStream不指望。


看來,Java和C#不同意確切的品種「放氣」的壓縮算法,但我的測試中「壓縮」應該工作:

這將壓縮xmlData在Java中:

ByteArrayOutputStream baos = new ByteArrayOutputStream() 
OutputStream out = new GZIPOutputStream(baos); 
out.write(xmlData); 
out.close(); 
byte[] compressedBytes = baos.toByteArray(); 

這在C#中解壓縮input

using (MemoryStream inputStream = new MemoryStream(input)) 
{ 
    using (GZipStream gzip = new GZipStream(inputStream, CompressionMode.Decompress)) 
    { 
    using (StreamReader reader = new StreamReader(gzip, System.Text.Encoding.UTF8)) 
    { 
     return reader.ReadToEnd(); 
    } 
    } 
} 
+0

你對!是工作。非常感謝! – user1228323 2012-02-23 20:03:32

0

它看起來像@Joni薩爾onen已經給出了減壓問題的答案,所以我想補充一點關於架構的內容。爲了找出問題,你應該分開兩個問題。首先,你需要刪除一個壓縮文件。那麼你需要減壓。然後,分別專注於問題領域。你以後可以隨時「管」這兩個問題。

順便說一句,在許多情況下使用原始zip文件很有用。當某些事情沒有按計劃進行時,它變成了一個安全網,尤其是,如果您只有一次機會捕獲該文件。