如何从字节数组创建 XpsDocument?

发布于 2024-11-18 19:25:41 字数 1431 浏览 4 评论 0原文

我想从字节数组创建一个新的 System.Windows.Xps.Packaging.XpsDocument 对象,因为我不想立即将其存储在本地计算机上。

通过使用临时文件,它可以正常工作:

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

但是,我想要完成的更像是这样:

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

上述方法的用法如下:

XpsDocument xps = TaxReturnCreator.OpenXpsDocument(tempFileUrl);
documentViewer1.Document = xps.GetFixedDocumentSequence();

并且,使用最后描述的尝试在 WPF 窗口中显示 XPS 内容的方法(不保存)崩溃并出现 System.ObjectDisposeException(“无法访问关闭的流”)(第一种方法工作正常)。

创建 XpsDocument 后我是否应该仍然保持流打开,或者我是否遗漏了其他内容? 也许有人知道一种完全不同/更好的方法来通过网络以字节形式检索 XPS 数据并从数据创建 XpsDocument 对象?

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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

段念尘 2024-11-25 19:25:41

您无法关闭支持 XpsDocument 的流。您必须允许该包管理后备 MemoryStream,一旦收集该包,就会收集该内存流。这样做似乎有点异端邪说:

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

但这就是必须要做的事情。

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.

盗梦空间 2024-11-25 19:25:41

您应该尝试包含

XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.SuperFast, url);

using 块中,即

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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文