如何在C#中编辑文件夹中的一些文本文件?

时间:2013-06-23 06:16:50

标签: c#

我在一个文件夹(1800个文件)中有许多文本文件,所有文件都具有相同的格式。他们这样开始:

“Station ABDEHGAH_ Lat = 30 27 Long = 51 2

1998 1 35050

1998 2 27800

1998 3 39500

1998 4 0“

我想编辑所有这些内容的第一行,使其如下所示: “ABDEHGAH 30.27 51.2”

我该怎么办?

3 个答案:

答案 0 :(得分:2)

您必须使用_Lat =搜索并替换"",并在所有文件中将Long =替换为""。它将涉及三个步骤:

  1. 您必须遍历文件夹中的所有文件。使用http://msdn.microsoft.com/en-us/library/bb513869.aspx

  2. 阅读每个文件的内容。使用http://msdn.microsoft.com/en-us/library/vstudio/ezwyzy7b.aspx

  3. 对于每个文件,请查找_Lat =Long =,并将其替换为""。使用String.Replace方法。请注意,仅当String.Replace_Lat =在所有文件中一致时,您才能使用Long =。我的意思是,如果在其中一个文件中它是Station ABDEHGAH_ Lat = 30 27 Long = 51 2而在另一个文件中它是Station ABDEHGAH_ Lat = 30 27 Long=51 2。注意空间。如果不一致,则必须使用RegEx.Replace查找模式并替换它们。

答案 1 :(得分:2)

此代码有效,请尝试:

string[] files = Directory.GetFiles(@"C:\Users\User\Desktop\AnyFolder");   // You should include System.IO;

foreach (string s in files)
{
    string text = File.ReadAllText(s);
    text = text.Replace("old text", "new text");
    StreamWriter writer = new StreamWriter(s);
    writer.Write(text);
}

如果此代码可以帮助您投票。

答案 2 :(得分:1)

The full source for this approach here (Github)

我创建了两个字符串来保存测试的路径

private readonly string sourceFiles = @"temp\source";
private readonly string outputFiles = @"temp\output";

我创建了compiled Regular Expression。这个表达式将:

  • 忽略第一个字
  • 捕获一个单词(仅限A-Z)并忽略其他字符,例如_
  • Lat =之后捕获一个数字,如果出现另一个以空格分隔的数字
  • Long =之后捕获一个数字,如果出现另一个以空格分隔的数字

正则表达式:

private readonly Regex firstLineParser =
    new Regex(@"^[^ ]+ (?<StationName>[a-z]+).* Lat = (?<Lat>\d+(\s\d+)?) Long = (?<Long>\d+(\s\d+)?)$"
        , RegexOptions.Compiled | RegexOptions.IgnoreCase
    );

这意味着我将有3个组,我可以访问它们来操纵值。

因此,为了测试我使用Stopwatch

的性能
public void Run()
{
    // performance test
    var timer = new Stopwatch();

    timer.Start();

Parallel.ForEach将使用线程并行运行遍历所有元素,这对于在大量文件上执行任务时是个好主意。

    Parallel.ForEach(Directory.GetFiles(sourceFiles), f =>
    {

现在,对于每个元素(完整文件路径),我们将创建一个StreamReader

        using (var sr = new StreamReader(f))
        {
            // retrieves just the name of the file
            // after a few tests, it seems to be faster
            // than instantiating a FileInfo, not a big deal though
            var outfilename = f.Split('\\').Last();

            // reads the first line from the source file
            string line = sr.ReadLine();

            // run the expression to match the values
            // we want to separate
            var match = firstLineParser.Match(line);

            // now that we have the groups, we can format
            // the values the way we want
            line = String.Format("{0} {1} {2}"
                , match.Groups["StationName"].Value
                , match.Groups["Lat"].Value.Replace(" ", ".")
                , match.Groups["Long"].Value.Replace(" ", ".")
            );

以下内容将创建StreamWriter

            using (var sw = new StreamWriter(Path.Combine(outputFiles, outfilename)))
            {
                // we modified the first line, so lets write it
                sw.WriteLine(line);

                // now we just rewrite all remaining lines
                while ((line = sr.ReadLine()) != null)
                    sw.WriteLine(line);

                // and write to disk
                sw.Flush();
            }
        }
    });

最后我们停止计时器并显示已用时间。

    timer.Stop();

    Console.WriteLine(timer.Elapsed.ToString(@"mm\:ss\.fff"));
}