代码之家  ›  专栏  ›  技术社区  ›  juergen d

压缩内存并使用base64进行编码

  •  0
  • juergen d  · 技术社区  · 12 年前

    我想在内存中压缩一个SVG文件,并用base64对其进行编码(我想将压缩后的/base64 SVG保存在XML文件中)。

    这就是我所拥有的(但我对一切都持开放态度):

    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,但这不是我的文件,因为它只有几个字符长。

    2 回复  |  直到 12 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    您的代码存在多个问题。

    最重要的是,你正在打开一个 StreamWriter 以写入二进制数据。您已经:

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

    流写入程序 用于写入 文本 。您的电话最终解决了 TextWriter.Write(object) 。结果就好像你打过电话一样:

    sw.Write(svg.ToString());
    

    它将输出类的名称( "System.Byte[]" ). 这就是为什么你得到的是13个字节长。它还指出了另一个问题(见下文)。

    所以你需要做的第一件事就是放弃 流写入程序 并具有:

        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 数组。

    看看PackageAPI,我看不出有什么方法可以为您提供特定部分的压缩数据流。

    简而言之,我认为您需要编写整个包,转换 那个 到base-64,并将其返回,如中所示 Alexei's answer .

        2
  •  2
  •   Alexei Levenkov    12 年前

    你不是在寻找一条通向起点的溪流。最简单的修复方法是使用 ToArray 处置前的权利 MemoryStream :

    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());
    }