我们正在尝试根据特定条件来操纵Word文档以删除段落。但是,当我们尝试使用错误打开它时,产生的单词文件总是以损坏的方式结束:
单词发现不可读的内容
下面的代码破坏了文件,但是如果我们删除该行:
Document document = mdp.Document;
文件已保存并打开,没有问题。我有明显的问题想念吗?
var readAllBytes = File.ReadAllBytes(@"C:\Original.docx");
using (var stream = new MemoryStream(readAllBytes))
{
using (WordprocessingDocument wpd = WordprocessingDocument.Open(stream, true))
{
MainDocumentPart mdp = wpd.MainDocumentPart;
Document document = mdp.Document;
}
}
File.WriteAllBytes(@"C:\New.docx", readAllBytes);
更新:
using (WordprocessingDocument wpd = WordprocessingDocument.Open(@"C:\Original.docx", true))
{
MainDocumentPart mdp = wpd.MainDocumentPart;
Document document = mdp.Document;
document.Save();
}
在物理文件上运行上面的代码,我们仍然可以打开Original.docx而不会出现错误,因此它似乎仅限于修改流。
答案 0 :(得分:0)
这是一种将文档读入MemoryStream
的方法:
public static MemoryStream ReadAllBytesToMemoryStream(string path)
{
byte[] buffer = File.ReadAllBytes(path);
var destStream = new MemoryStream(buffer.Length);
destStream.Write(buffer, 0, buffer.Length);
destStream.Seek(0, SeekOrigin.Begin);
return destStream;
}
请注意如何实例化MemoryStream
。我传递的是容量而不是缓冲区(就像您自己的代码一样)。为什么会这样?
使用MemoryStream()
或MemoryStream(int)
时,您正在创建可调整大小的MemoryStream
实例,以防您对文档进行更改。使用MemoryStream(byte[])
时(如您的代码一样),MemoryStream
实例不可调整大小,除非您不对文档进行任何更改或更改只会使其缩进,否则这将是有问题的大小。
现在,要将Word文档读入MemoryStream
,在内存中处理该Word文档并以一致的MemoryStream
结尾,您将必须执行以下操作:
// Get a MemoryStream.
// In this example, the MemoryStream is created by reading a file stored
// in the file system. Depending on the Stream you "receive", it makes
// sense to copy the Stream to a MemoryStream before processing.
MemoryStream stream = ReadAllBytesToMemoryStream(@"C:\Original.docx");
// Open the Word document on the MemoryStream.
using (WordprocessingDocument wpd = WordprocessingDocument.Open(stream, true)
{
MainDocumentPart mdp = wpd.MainDocumentPart;
Document document = mdp.Document;
// Manipulate document ...
}
// After having closed the WordprocessingDocument (by leaving the using statement),
// you can use the MemoryStream for whatever comes next, e.g., to write it to a
// file stored in the file system.
File.WriteAllBytes(@"C:\New.docx", stream.GetBuffer());
请注意,只要您的下一个操作取决于该stream.Position
属性(例如stream.Seek(0, SeekOrigin.Begin)
,{{1}),就必须通过调用MemoryStream.Position
来重置CopyTo
属性}。离开using语句后,流的位置将等于其长度。