我想在内存中压缩SVG文件并使用base64对其进行编码(我想将zipped / 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,但这不是我的文件,因为它只有几个字符长。
答案 0 :(得分: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,我没有看到一个方法可以为您提供特定部分的压缩数据流。
简而言之,我认为您需要编写整个包,将 转换为base-64,然后将其返回,如Alexei's answer所示。
答案 1 :(得分:2)
你不是在开始寻找流。最简单的解决方法是在处置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());
}