How to create an XpsDocument from byte array?
I would like to create a new System.Windows.Xps.Packaging.XpsDocument object from byte array, as I will not want to store it immediately on a local machine.
By 开发者_C百科using a temp file it works fine:
public static XpsDocument OpenXpsDocument(string url)
{
WebClient webClient = new System.Net.WebClient();
byte[] data = webClient.DownloadData(url);
using (BinaryWriter writer = new System.IO.BinaryWriter(File.OpenWrite(xpsTempFilePath)))
{
writer.Write(data);
writer.Flush();
}
XpsDocument xpsDocument = new System.Windows.Xps.Packaging.XpsDocument(xpsTempFilePath, FileAccess.Read);
return xpsDocument;
}
However, what I want to accomplish is more like this:
public static XpsDocument OpenXpsDocument(string url)
{
WebClient webClient = new WebClient();
byte[] data = webClient.DownloadData(url);
Package package;
using (Stream stream = new MemoryStream(data))
{
package = System.IO.Packaging.Package.Open(stream);
}
XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.SuperFast, url);
return xpsDocument;
}
Usage of the aforementioned methods goes like that:
XpsDocument xps = TaxReturnCreator.OpenXpsDocument(tempFileUrl);
documentViewer1.Document = xps.GetFixedDocumentSequence();
And, using the last-described method of trying to display the XPS content in a WPF window (without saving) crashes with a System.ObjectDisposedException ("Cannot access a closed Stream") (First method works fine).
Am I supposed to still keep the Stream open after creating the XpsDocument or am I missing something else? Maybe someone knows a completely different / better method of retrieving XPS data as bytes over network and creating an XpsDocument object from the data?
You cannot close a stream backing an XpsDocument. You must allow the Package to manage the backing MemoryStream, which will be collected once this Package is collected. It may seem a bit of a heresy to do the following:
public static XpsDocument OpenXpsDocument(string url)
{
var webClient = new WebClient();
var data = webClient.DownloadData(url);
var package = System.IO.Packaging.Package.Open(new MemoryStream(data));
var xpsDocument = new XpsDocument(package,
CompressionOption.SuperFast,
url);
return xpsDocument;
}
but it is how this must be done.
You should try including
XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.SuperFast, url);
into using
block, i.e.
Package package;
using (Stream stream = new MemoryStream(data))
{
package = System.IO.Packaging.Package.Open(stream);
XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.SuperFast, url);
}
return xpsDocument;
精彩评论