Arcadian
Arcadian

Reputation: 1373

txt file read/overwrite/append. Is this feasible? (Visual C#)

I'm writing a program for some data entry I have to periodically do. I have begun testing a few things that the program will have to do but i'm not sure about this part.

What i need this part to do is:

read a .txt file of data

take the first 12 characters from each line

take the first 12 characters from each line of the data that has been entered in a multi-line text box

compare the two lists line by line

if one of the 12 character blocks from the multi-line text box match one of the blocks in the .txt file then overwrite that entire line (only 17 characters in total)

if one of the 12 character blocks from the multi-line text box DO NOT match any of the blocks in the.txt file then append that entire line to the file

thats all it has to do.

i'll do an example:

TXT FILE:

G01:78:08:32 JG05
G08:80:93:10 JG02
G28:58:29:28 JG04

MULTI-LINE TEXT BOX:

G01:78:08:32 JG06
G28:58:29:28 JG03
G32:10:18:14 JG01
G32:18:50:78 JG07

RESULTING TXT FILE:

G01:78:08:32 JG06
G08:80:93:10 JG02
G28:58:29:28 JG03
G32:10:18:14 JG01
G32:18:50:78 JG07

as you can see lines 1 and 3 were overwriten, line 2 was left alone as it did not match any blocks in the text box, lines 4 and 5 were appended to the file.

thats all i want it to do.

How do i go about this?

Thanks in advance

Edit

The code i'm using is this:

        private void WriteToFile()
    {
         // Read all lines from file into memory
        System.IO.StreamReader objReader = new System.IO.StreamReader("Jumpgate List.JG");
        List<String> fileTextList = new List<String>();
                 do
                     {
                         fileTextList.Add(objReader.ReadLine());
                     }
                 while (objReader.Peek() != -1);

                 objReader.Close();

         // Read all lines from the Input textbox into memory
             System.IO.StringReader objReaderi = new System.IO.StringReader(txtInput.Text);
             List<String> inputTextList = new List<String>();
                 do
                     {
                         inputTextList.Add(objReaderi.ReadLine());
                     } 
                 while (objReaderi.Peek() != -1);

                 objReaderi.Close();

         for(int i=0;i<fileTextList.Count;i++)
             {
                 for(int j=0;j<inputTextList.Count;j++)
                  //compare the first 12 characters of each string
                  if (String.Compare(fileTextList[i], 0, inputTextList[j], 0, 12) == 0) // strings are equal
                     {
                       //replace the fileTextList string with the inputTextList string
                         fileTextList[i] = inputTextList[j];
                       // now that you have matched you inputTextList line you remember not to append it at the end
                        inputTextList[j] = String.Empty; // or nothing
                     }
             }

          for(int i=0;i<inputTextList.Count;i++)
             {
                 if (!string.IsNullOrEmpty(inputTextList[i])) fileTextList.Add(inputTextList[i]);
              }

          System.IO.StreamWriter objWriter = new System.IO.StreamWriter("Jumpgate List.JG");

          // Overwrite the Jumpgate List.JG file using the updated fileTextList
          objWriter.Write(fileTextList);

          objWriter.Close();

}

However, when i open the txt file all i get is: System.Collections.Generic.List`1[System.String]

Upvotes: 2

Views: 959

Answers (3)

Ando
Ando

Reputation: 11409

I'm not going to write the whole code for doing this but it would be something like this:

Disclaimer: I have not used a code editor to try the code, just wrote it here, hopefully you'll get the idea and fill in the missing pieces :)

1) get all the lines in the file in a list. Something like this

        StreamReader rd = new StreamReader("sadasd");
        List<String> llist = new List<String>();
            do
            {
                llist.Add(rd.ReadLine());

            } while (rd.Peek() != -1);

2) get all the lines in your multiline text box (the procedure should be similar to the one above): multiTextList

3) now that you can compare the content of the 2 lists iterating through them

for(int i=0;i<fileTextList.Count;i++)
{
    for(int j=0;j<multiTextList.Count;j++)
     //compare the first 12 characters of each string
     if String.Compare(fileTextList[i], 0, multiTextList[j], 0, 12) == 0 // strings are equal
{
      //replace the initial line with whatever you want
       fileTextList[i] = //whatever
      // now that you have matched you multiTextList line you remember not to append it at the end
       multiTextList[j] = String.empty // or nothing
}
}

4) at the end you will have in fileTextList the initial rows, modified where necessary In multiTextList you will have only the lines that were not matched so we add them to the initial file rows

      for(int i=0;i<multiTextList.Count;i++)
        {
if !string.isnullorempty(multitextlist[i]) fileTextList.add(multitextlist[i])
         }

5) now in fileTextList you have all the rows you require so you can print them one by one in a file and you have your result

 StringBuilder lSb = new StringBuilder();
            for (int i = 0; i < fileTextList.Count; i++)
            {
                lSb.AppendLine(fileTextList[i]);
            }
            File.WriteAllText(@"C:/test2.txt",lSb.ToString());

In C:/test2.txt you should have the results.

Hope this helps!

Upvotes: 1

Josh Sterling
Josh Sterling

Reputation: 848

if the file is large, loading the entire file into a dictionary to update a handful of lines from a textfield is probably excessive.

In pseudocode I would probably:

Create a list of booleans or other structure to track if a line was matched.

open the file in read/write mode.


For each line in file
{
  for each unmatched line in text field 
  {
    If stamps match
      Update file
      record that it was matched
    }
}

for each unmatched line in text field
{
  append to file
}

If the lines are fixed width, you can probably optimize by only reading the stamp rather than the whole line. If they match your file pointer is in the right spot to start writing, if not you move to the next line.

Upvotes: 0

JSBձոգչ
JSBձոգչ

Reputation: 41378

// this variable maps the timestamps to complete lines
var dict = new Dictionary<string, string>();

// create the map of stamp => line for the original text file
string fileLine = file.ReadLine();
string fileStamp = fileLine.Substring(0, 12);
dict[fileStamp] = fileLine;

// now update the map with results from the text input. This will overwrite text
// strings that already exist in the file
foreach (string inputLine in textInputString.Split('\n'))
{
    string inputStamp = inputLine.Substring(0, 12);
    dict[inputStamp] = inputLine;
}

// write out the new file with the updated lines
foreach (string line in dict.Values)
{
    outputFile.WriteLine(line);
}

Upvotes: 1

Related Questions