在c#中并行读写文件

时间:2013-09-16 13:39:14

标签: c# task-parallel-library

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

3 个答案:

答案 0 :(得分:2)

您的Path.Combine()调用的repro是:

  var fileName = @"D:\Demo\foo.txt";
  var path = Path.Combine(@"D:\Demo2", fileName);

执行您认为的操作。它实际上会覆盖原始文件而不会向D:\ Demo2写入任何内容。修正:

  var path = Path.Combine(@"D:\Demo2", Path.GetFileName(fileName));

答案 1 :(得分:1)

您的文件集将包含完整的文件名,您的代码会假定部分(相对)名称。

       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()获得更大的提升,特别是对于许多文件。

答案 2 :(得分:-2)

除了其他答案之外:我想你想要做的是异步写入,而不是并行写入。并行调用时,您使用StreamWriter的实例有多个线程。 StreamWriter不是线程安全的,在你的代码片段中你不关心线程。您还希望并行化以顺序方式执行的工作。

我建议您使用WriteAsync个实例的StreamWriter方法。