如何使用多线程将多个文件从doc转换为docx



我有数百万个需要转换为docx的文档文件。我目前使用下面的方法来转换指定目录中的每个文件。我怎样才能有效地多线程这个进程?

static void ConvertDocToDocx(string path)
{
Application word = new Application();
var sourceFile = new FileInfo(path);
var document = word.Documents.Open(sourceFile.FullName);
string newFileName = sourceFile.FullName.Replace(".doc", ".docx");
document.SaveAs2(newFileName, WdSaveFormat.wdFormatXMLDocument,
CompatibilityMode: WdCompatibilityMode.wdWord2010);
word.ActiveDocument.Close();
word.Quit();
//File.Delete(path);
}

我目前的方法是使用Directory.GetFiles来创建我路径中的文件列表,然后使用Parallel.ForEach来转换文件。下面是我的代码:

string[] filesList = Directory.GetFiles(path);
Parallel.ForEach(filesList, new ParallelOptions { MaxDegreeOfParallelism = 20 }, file =>
{
if (file.Contains(".doc"))
{
ConvertDocToDocx(file);
}
});

然而,这似乎并没有提高性能。我是否误解了Parallel.ForEach的使用?

您正在自动使用Word,这相当于手动逐个打开文件并保存它们。这个方法可能有一个提高性能的可能性:不需要为每个文件创建新的Word实例,只需重用第一个实例。

...
var wordInstance = new Application();
try
{
var fileNameList = Directory.GetFiles(path);
foreach(var fileName in fileNameList)
{
if (fileName.Contains(".doc"))
{
ConvertDocToDocx(wordInstance, file);
}
}
}
finally
{
word.Quit();
}
...
static void ConvertDocToDocx(Application wordInstance, string path)
{
var sourceFile = new FileInfo(path);
var newFileName = sourceFile.FullName.Replace(".doc", ".docx");
var document = wordInstance.Documents.Open(sourceFile.FullName);
document.SaveAs2(
newFileName, 
WdSaveFormat.wdFormatXMLDocument,
CompatibilityMode: WdCompatibilityMode.wdWord2010);
wordInstance.ActiveDocument.Close();
//File.Delete(path);
}

但是正如其他人已经提到的,这是这种方法的局限性。你应该看看基于文件格式知识的解决方案,比如NPOI。它是一个c#重写的流行的Apache POI包,所以如果你搜索"POI转换文档到docx"并找到Java代码不用担心,几乎相同的代码也可以在c#下编译NPOI包,在大多数情况下,只需要轻微的语法更改。

最新更新