2013-09-26 48 views
0

我想壓縮內存中的SVG文件,並使用base64對其進行編碼(我想將zip/base64 SVG保存在XML文件中)。內存中的zip和base64編碼

這是我(但我願意接受一切):

byte[] svg = File.ReadAllBytes("test.SVG"); 
using (MemoryStream ms = new MemoryStream()) 
{ 
    using (Package pkg = Package.Open(ms, FileMode.Create)) 
    { 
     PackagePart part = pkg.CreatePart(new Uri("/test.SVG", UriKind.Relative), "image/svg+xml", CompressionOption.Normal); 
     using (Stream strm = part.GetStream()) 
     { 
      using (StreamWriter sw = new StreamWriter(strm)) 
      { 
       sw.Write(svg); 
      } 

      byte[] b = ReadToEnd(part.GetStream()); 
      return Convert.ToBase64String(b); 
     } 
    } 
} 

它的東西轉換爲base64但是這不是我的文件,因爲它是長只有幾個字符。

+0

'ReadToEnd(part.GetStream())'看起來不對。 – user2246674

+0

這是我遺漏的一個函數,因爲它有點長。它將一個流複製到一個字節數組。但我從網上覆制它,我認爲它很好。 –

+0

我希望50kb文件的base64字符串長度超過13個字符:) –

回答

2

你不是在尋找開始的流。最簡單的解決是正確的處置MemoryStream前使用ToArray

using (MemoryStream ms = new MemoryStream()) 
{ 
    // Whatever manipulations with stream you need goes here. 
    ... 
    ms.Close(); // guarantees to commit all changes, 
       // safe to do as `ToArray` work on disposed stream 
    return Convert.ToBase64String(ms.ToArrray()); 
} 
+0

如果我趕上字節數組,並將其寫入編碼前的拉鍊,然後有2個文件在壓縮:content_types.xml和test.svg,但只有1 KB大,已經不是原來的圖像。 –

+0

@juergend你確定test.svg文件是正確的(什麼是'svg.Length'?)也是爲什麼你正在使用'StreamWriter'節省字節,而不是'Stream.Write'或再時效SVG作爲串並寫它'StreamWriter.Write(string)'? - 用StreamWriter loks寫入字節錯誤... –

+1

+1。究竟。而且,是的,「StreamWriter」是他沒有獲取太多數據的原因。詳情請參閱我的回答。 –

3

有你的代碼多個問題。

最重要的是,您打開一個StreamWriter來編寫二進制數據。您有:

byte[] svg; 

... 

using (StreamWriter sw = new StreamWriter(...)) 
{ 
    sw.Write(svg); 
} 

StreamWriter是用來寫文本。你的電話最終解決到TextWriter.Write(object)。其結果是,如果你曾呼籲:

sw.Write(svg.ToString()); 

將輸出類("System.Byte[]")的名稱。這就是爲什麼你得到的是13個字節長。它也指出了另一個問題(見下文)。

所以,你需要做的第一件事就是溝StreamWriter和有:

using (Stream strm = part.GetStream()) 
    { 
     strm.Write(svg, 0, svg.Length) 
    } 

也就是說,至少,會寫上你要流數據。

現在,至於閱讀,你有一個問題。你也許可以接着寫:

 strm.Flush(); 
     strm.Position = 0; 
     byte[] b = ReadToEnd(part.GetStream()); 
     return Convert.ToBase64String(b); 

我不知道你的ReadToEnd方法做什麼。也許它定位流並讀取所有內容。但這不會給你想要的,這是我提到的另一個問題。

通過part.GetStream返回的流重寫Read方法和解壓縮數據。因此,您返回的字節數組將與您編寫的原始數組svg相同。

看看Package API,我沒有看到一個方法可以給你一個特定部分的壓縮數據流。

總之,我認爲你需要寫整個包,轉換立足-64,並返回,如圖Alexei's answer

+0

感謝您的詳細解釋。讓我更進一步。 ?拉鍊本身(我做了'File.WriteAllBytes(「tst.zip」,B);'是腐敗雖然 –

+1

@juergend:你讀一個完整的答案「文件」可以通過調用得到'ReadToEnd'不將成爲一個有效的zip文件,你必須編寫整個包,你不能提取一個單獨的部分。 –