【问题标题】:Selection.InsertFile fails with "disk is full" error messageSelection.InsertFile 失败并显示“磁盘已满”错误消息
【发布时间】:2018-08-28 07:19:29
【问题描述】:

使用 c# 和 Interop Word 我试图将指定目录中的所有文件合并到一个新文档中。我的代码遍历文件名列表并使用“InsertFile”将每个文件名添加到选择中。

文件很多,一段时间后进程失败。错误信息如下:

磁盘已满。释放此驱动器上的一些空间,或将文档保存在另一个磁盘上。
尝试以下一项或多项:

  • 关闭所有不需要的文档、程序和窗口。
  • 将文档保存在另一个磁盘上。”

在 InsertFile 失败时,选择使用了大约 7MB。我的磁盘有 300GB 的可用空间,机器有 32GB 的 RAM。

我保存的文件中没有任何图形或数学。

我做错了什么?在 foreach 循环内的 InsertFile 行(如下)引发了异常。

代码稍后会出现。请注意,我从一个 winword 实例开始,它是一个名为 PrintObj 的类的成员。另外,请注意,如果我将它用于少量文件(例如 100-200),则此代码可以正常工作。

Document mergeDoc = PrintObj.WinWord.Documents.Add(ref missing, ref missing, 
     ref missing, ref missing);
mergeDoc.PageSetup.LeftMargin = globalPrintObj.WinWord.InchesToPoints(0.5f);
        mergeDoc.PageSetup.RightMargin =  

PrintObj.WinWord.InchesToPoints(0.5f);

string[] filePaths = Directory.GetFiles(directoryPath, "*.docx");
string[] documentsToMerge = filePaths;
Array.Sort(documentsToMerge);

// Make a Word selection object.
Selection selection = PrintObj.WinWord.Selection;

//A counter that signals that we shoudn't insert a page break at the end of 
document.
int breakStop = 0;

//Count the number of documents to insert;
int documentCount = documentsToMerge.Length;

// Loop thru each of the Word documents
foreach (string file in documentsToMerge)
{
    breakStop++;
    // Insert the files to our template
    selection.InsertFile(file, ref missing, ref missing, ref missing, 
      ref missing);
    if (breakStop != documentCount)
    {
        selection.InsertBreak(ref pageBreak);
    }
}
Directory.CreateDirectory(directoryPath);

//Save the document
obj wordFileName = fileNameWithExtension;
mergeDoc.SaveAs2(ref wordFileName);

【问题讨论】:

  • Word 将所有更改写入“临时文件”,部分原因是为了维护其撤消列表。如果这些超过一定大小,您可能会收到您所看到的错误。有两件事可以提供帮助,将它们构建到您的代码中以间隔执行(例如,通过循环 n 次):1)mergedoc.UndoClear()mergeDoc.Save(ref oTrue, ref missing);

标签: c# ms-word interop


【解决方案1】:

你能用文件名检查路径吗?

前段时间我记得因为 255 个字符的问题而收到磁盘已满的错误,可能其中一个文件的路径太长了

https://support.code42.com/CrashPlan/4/Troubleshooting/Windows_file_paths_longer_than_255_characters

尝试将文件保存在其他目录中,例如 C:\YourFolder

【讨论】:

  • 对于文件名长度我已经有一个验证(在上面的 sn-p i 中没有看到)。我昨晚深夜尝试保存到另一个文件夹,但我的代码不起作用。会再试一次。同时我正在考虑一个不同的解决方案......我认为由于内存分配问题(我不知道如何调整或刷新),选择对象的大小变得太大了。我正在考虑将选择更改为当前选择的结尾(不确定如何),然后添加分页符并附加下一个文件,然后在循环继续时再次执行。当我知道更多时会发布
  • 尝试使用 Document.Range 或 Document.Content 对象而不是选择。选择总是一个非常糟糕的主意,应尽可能避免。
  • LocEngineer - 谢谢。还是有问题。使用 Document.Content.InsertFile,我可以添加一个文件,然后将其替换为下一个 InserFile。我一直无法让它附加多个文件(目录中有超过 1000 个 docx 文件。感谢任何想法
【解决方案2】:

最终我放弃了 MS 程序集并使用 Xceed.Words.NET 来解决这个问题,这很有效。使用 Selection 对象时,进程总是在大约 840 个插入文档后挂起(插入文档的确切数量始终相同),这是一个问题,因为我需要插入超过 1200 个文件。最终文档目前刚刚超过 15,706,000 个字符和超过 11,700 页,并且刚刚超过 4MB。 在我看来,这是 Interop Word 文档类中的一个缺陷,因为附加文档是一个非常常见的用例。 ((注意几周后添加 - 每次插入完成时都有机会返回并尝试添加一个计数器,然后

if (Counter % 100 == 0)
 {
    mergeDoc.UndoClear();
 }

这行得通。感谢 CM 的建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2015-02-02
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    相关资源
    最近更新 更多