使用包打开 XPS 文件会保持文件锁定

Posted

技术标签:

【中文标题】使用包打开 XPS 文件会保持文件锁定【英文标题】:Opening an XPS file using package keeps file locked 【发布时间】:2018-06-28 19:28:26 【问题描述】:

以下 C# 代码保持文件锁定,因此 DeleteFile 失败:

String srcFile = @"D:\I\deleteme\TempFiles\Mem\XPS\1.xps";

Package package = Package.Open(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);

XpsDocument xpsDoc = new XpsDocument(package, CompressionOption.Normal, srcFile);

/* Calling this is what actually keeps the file open.
   Commenting out the call to GetFixedDocumentSequence() does not cause lock */
FixedDocumentSequence fds = xpsDoc.GetFixedDocumentSequence();

xpsDoc.Close();
package.Close();

File.Delete(srcFile); /* This will throw an exception because the file is locked */

非常相似的代码,从文件而不是包打开 XpsDocument 不会保持文件锁定:

String srcFile = @"D:\I\deleteme\TempFiles\Mem\XPS\1.xps";

XpsDocument xpsDoc = new XpsDocument(srcFile, FileAccess.Read, CompressionOption.Normal);

/* If XpsDocument is opened from file instead of package,
   GetFixedDocumentSequence() doesn't keep the file open */
FixedDocumentSequence fds = xpsDoc.GetFixedDocumentSequence();

xpsDoc.Close();

File.Delete(srcFile); /* This will throw an exception because the file is locked */

我看到另一个帖子说如果你从文件中打开文档,你需要手动关闭底层包,但对我来说似乎不是这样。

我在这里放了一个项目和示例文件:https://drive.google.com/open?id=1GTCaxmcQUDpAophpsu_sC3_rK3p6Zv5z

【问题讨论】:

【参考方案1】:

您没有正确处理包裹。将其包装在 using 中很可能会解决问题:

String srcFile = @"D:\I\deleteme\TempFiles\Mem\XPS\1.xps";

using(Package package = Package.Open(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read))


    XpsDocument xpsDoc = new XpsDocument(package, CompressionOption.Normal, srcFile);

    /* Calling this is what actually keeps the file open.
       Commenting out the call to GetFixedDocumentSequence() does not cause lock 
    */
    FixedDocumentSequence fds = xpsDoc.GetFixedDocumentSequence();

    xpsDoc.Close();
    package.Close();


File.Delete(srcFile);

如果这不能解决问题,您可以考虑添加额外的 FileShare 值(特别是 FileShare.Delete),但这只会隐藏根本问题而不是解决它。

【讨论】:

我的意思是说我尝试过处理包。这不会改变行为。另外,我不想删除源文件。我只是想使用包来阅读它。我现在的解决方案很丑,如果源是我使用包打开的流,而如果源是文件,我必须直接从文件中打开文档。

以上是关于使用包打开 XPS 文件会保持文件锁定的主要内容,如果未能解决你的问题,请参考以下文章

msbuild.exe 保持打开状态,锁定文件

未能锁定文件无法打开磁盘..*.vmdk或者某一个快照所依赖的磁盘。”解决办法

PHP 利用文件锁处理高并发

PHP 利用文件锁处理高并发

PHP 利用文件锁处理高并发

OleDB 锁复制 .NET MS Access