在 C# 中并行读取和写入文件
本文关键字:文件 读取 并行 | 更新日期: 2023-09-27 18:31:38
我在 c# 中有以下代码片段,其中我并行读取文件并在读取后替换一些文本,然后写回不同的位置。我没有收到任何异常,但文件没有写入其他位置
class Program
{
private static readonly object _loc = new object();
public static string FileRead(string fileName)
{
string pattern = @"the";
var result = File.ReadAllText(fileName);
var replacedText = Regex.Replace(result, pattern, "XXXX");
var path = Path.Combine(@"D:'Demo2", fileName);
using (StreamWriter sw = new StreamWriter(path, false))
sw.Write(replacedText);
return replacedText;
}
static void Main(string[] args)
{
var files = Directory.GetFiles(@"D:'Demo", "*.txt");
Parallel.ForEach(files, x =>
{
Console.WriteLine("FileName={0}'tNOC={1}",x, FileRead(x).Length);
});
Console.ReadLine();
}
}
Path.Combine() 调用的重现是:
var fileName = @"D:'Demo'foo.txt";
var path = Path.Combine(@"D:'Demo2", fileName);
这不会做你认为它做的事情。 它实际上会覆盖原始文件,而不会向 D:''Demo2 写入任何内容。 修复:
var path = Path.Combine(@"D:'Demo2", Path.GetFileName(fileName));
您的文件集合将包含完整的文件名,您的代码采用部分(相对)名称。
public static string FileRead(string fileName)
{
...
//var path = Path.Combine(@"D:'Demo2", fileName);
var path = Path.GetFilename(fileName); // check 'path' in debugger
path = Path.Combine(@"D:'Demo2", path);
...
}
======
一些一般性评论:
- 并行 I/O 并不总是有效。您的
D:'
最好是SSD,但即便如此。 - 您将从中获得更大的提升
Directory.EnumerateFiles()
,尤其是对于许多文件。
除了其他答案:我想你想做的是异步编写,而不是并行编写。并行调用此函数时,您有多个线程使用 StreamWriter
的实例。该StreamWriter
不是线程安全的,在您的代码段中,您不关心线程。您还希望并行化无论如何以顺序方式执行的工作。
我建议使用您的StreamWriter
实例的WriteAsync
方法。