I want to zip a SVG file in memory and encode it with base64 (I want to save the zipped/base64 SVG in a XML file).
This is what I have (but I am open to everything):
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);
}
}
}
It convert something to base64 but that is not my file since it is only a few characters long.
There are multiple problems with your code.
Most importantly, you're opening a StreamWriter
to write binary data. You have:
byte[] svg;
...
using (StreamWriter sw = new StreamWriter(...))
{
sw.Write(svg);
}
StreamWriter
is used to write text . The call you have ends up resolving to TextWriter.Write(object)
. The result is as if you had called:
sw.Write(svg.ToString());
Which will output the name of the class ( "System.Byte[]"
). That's why what you're getting is 13 bytes long. It also points to another problem (see below).
So the first thing you need to do is ditch the StreamWriter
and have:
using (Stream strm = part.GetStream())
{
strm.Write(svg, 0, svg.Length)
}
That, at least, will write the data you want to the stream.
Now, as for reading, you have a problem. You probably can then write:
strm.Flush();
strm.Position = 0;
byte[] b = ReadToEnd(part.GetStream());
return Convert.ToBase64String(b);
I don't know what your ReadToEnd
method does. Perhaps it positions the stream and reads everything. But that's not going to give you what you want, which is the other problem I alluded to.
The stream returned by part.GetStream
overrides the Read
method and decompresses the data . So the byte array you get back will be the same as the original svg
array that you wrote.
Looking at the Package API, I don't see a method that will give you the compressed data stream for a particular part.
In short, I think you need to write the entire package, convert that to base-64, and return it, as shown in Alexei's answer .
You are not seeking the stream to the beginning. Easiest fix is to use ToArray
right before disposing 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());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.