0

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

3 回答 3

2

您的 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));
于 2013-09-16T13:49:58.113 回答
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(),尤其是对于许多文件。
于 2013-09-16T13:45:39.630 回答
-2

除了其他答案:我想您想要做的是异步编写,而不是并行编写。当并行调用它时,您有多个线程使用您的StreamWriter. 不是线程安全的StreamWriter,在您的代码段中您不关心线程。无论如何,您还希望并行化以顺序方式执行的工作。

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

于 2013-09-16T13:51:12.200 回答