2013-09-26 64 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文件,你必须编写整个包,你不能提取一个单独的部分。 –