0

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);
sosNiLa
  • 289
  • 6
  • 18

2 Answers2

0

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.

Behrooz
  • 1,696
  • 2
  • 32
  • 54
  • Hello @Behrouz, It should be an C# app which should be run every 2 hours. Thanks for your suggestions, I will give it a try. – sosNiLa Sep 11 '19 at 08:34
  • @Behrouz, I went with the A solution, but my output file is contain old data. I have confirmed through debug and breakpoint that item of array is updated but like I said, not being placed in output file. I will edit the question with the code I was using now. – sosNiLa Sep 11 '19 at 09:42
  • @sgsniko1 You will have to either use `ref` variables or after updating an item put it back into the array, like so: `items[3] = items[3].Replace ("A111", "A555")`. I just read your edit. you should either add your `row` variable to another array or `List` after each iteration of loop. or open the destination file for write and `WriteLine` to it. Also don't forget to rejoin your split string with `string.Join()`. Also, if you have empty columns in your input, you might want to supply an extra argument to `string.Split()` to indicate you want to keep empty entries. – Behrooz Sep 11 '19 at 10:08
  • To be honest, I am little lost... is it possible to give me some code example? Oh and its not an option to open destination file and WriteLine to it, I have to read the file, change whats necessary in the code, save it and move it to a new location. – sosNiLa Sep 11 '19 at 11:10
0

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);
Behrooz
  • 1,696
  • 2
  • 32
  • 54
OOzgun
  • 36
  • 6
  • @Behrouz, thank you, this is very clear, but I have another issue because string "A111" is repeating in the line... So considering its a fixed length, I tried using substring to find the string I need to replace. The string is always 4 characters long and always start at index of 250. if (rows[i].Substring(250, 4) == "A111") { rows[i] = rows[i].Replace("A111", "A555"); } This is what I have tried, but the problem is that "A111" string is replaced on other places also, not just on index 250. Any hint what I am doing wrong? Thanks – sosNiLa Sep 17 '19 at 12:44
  • I have managed to solve it this way if (rows[i].Substring(250, 4) == "A111") { rows[i] = rows[i].Remove(250, 4).Insert(250, "A555"); } – sosNiLa Sep 17 '19 at 13:27