C# - 读取、编辑和保存固定长度文件

C# - Read, Edit & Save FixedLength file

我需要读取 FixedLenght 文件,编辑其中的一些数据,然后将该文件保存到某个位置。这个应该做所有这些的小应用程序应该每 2 小时 运行。

这是文件的例子:

14000 美国 A111 78900

14000 美国 A222 78900

14000 美国 A222 78900

我需要查找 A111 和 A222 等数据,并将所有 A111 替换为例如 A555。我试过使用 TextFieldParser 但没有任何运气......这是我的代码。我能够获取数组元素,但我不确定下一步该做什么...

    using (TextFieldParser parser = 
    FileSystem.OpenTextFieldParser(sourceFile))
        {
            parser.TextFieldType = FieldType.FixedWidth;
            parser.FieldWidths = new int[] { 6, 3, 5, 5 };

            while (!parser.EndOfData)
            {
                try
                {
                    string[] fields = parser.ReadFields();
                    foreach (var f in fields)
                    {
                        Console.WriteLine(f);
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }

这是 Berkouz 的解决方案,但仍然存在问题,当保存到文件时,数组的项目不会在输出中被替换。代码:

        string[] rows = File.ReadAllLines(sourceFile);

        foreach (var row in rows)
        {
            string[] elements = row.Split(' ');

            for (int i = 0; i < elements.Length; i++)
            {
                if (elements.GetValue(i).ToString() == "A111") {
                    elements.SetValue("A555", i);
                }
            }
        }

        var destFile = targetPath.FullName + "\" + "output.txt";

        File.WriteAllLines(destFile, rows);

这看起来像一个 AB 问题。如果这是一次性的事情,我建议您改用 sed
调用很简单:sed -e 's/A111/A555/g' 如果您的文件内容更复杂,您可以使用 awkperl pcre 正则表达式功能。

如果这实际上不是一次性的事情并且您想用 C# 编写它,您可以:
A) 使用 System.IO.File.ReadAllLines(),使用 string.Split() 拆分文本,使用 string.Replace() 替换你想要的项目,然后使用 WriteAllLines()
写回 B) 使用 MemoryMappedFile。这样,您就不必担心写任何东西。但它往往会变得有点尖锐,您应该小心 BOM。

还有很多其他方法,这些是 easy/slow/clean 和 fast/efficient/ugly 代码的两端。

注意行 [rowIndex] 分配给的行。这是因为字符串不变性迫使替换和类似函数具有输出值(而不是修改它们的输入),您必须将其分配回数据存储(无论它是什么,在这种情况下是一个数组)。

        var rows = File.ReadAllLines(sourcefile);
        for (int rowIndex = 0; rowIndex != rows.Length; rowIndex++)
            rows[rowIndex] = rows[rowIndex].Replace("A111", "A555");
        File.WriteAllLines(destFile, rows);