在 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();
    }
}

在 C# 中并行读取和写入文件

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方法。