C# - Read, Edit & Save FixedLength file

1.5k views Asked by At

I need to read FixedLenght file, edit some data inside of it and then save that file to some location. This little app which should do all this should be run every 2 hours.

This is the example of the file:

14000 US A111 78900

14000 US A222 78900

14000 US A222 78900

I need to look for data like A111 and A222, and to replace all A111 to for example A555. I have tried using TextFieldParser but without any luck... This is my code. I am able to get element of array but I am not sure what to do next...

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

This is solution by Berkouz, but still having issues, the items of array are not replaced in output when saved to a file. The code:

        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);
2

There are 2 answers

2
OOzgun On BEST ANSWER

Note the line where rows[rowIndex] is assigned to. that's because of string immutability forcing replace and similar functions to have an output value(as opposed to modifying their input) that you have to assign back to your data storage(whatever it may be, an array in this case).

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

This looks like an AB problem. If this is a one time thing, I suggest you use sed instead.
Invocation is simple: sed -e 's/A111/A555/g' In case your file contents are more complex you can use awk, perl pcre regex features.

If this is in fact not a one-time thing and you want it written in C#, you can:
A) use System.IO.File.ReadAllLines(), split the text using string.Split(), replace the item you want using string.Replace() and write it back using WriteAllLines()
B) use a MemoryMappedFile. This way, you don't have to worry about writing anything. But it tends to get a little bit pointery and you should be careful with BOMs.

There are a LOT of other ways, these are the two ends of the spectrum for easy/slow/clean and fast/efficient/ugly code.