0

I have this little project in C# where I am manipulating with files. Now my task is that I have to delete specific rows from files.

For example my file looks like this:

1-this is the first line
2-this is the second line
3-this is the third line
4-this is the fourth line

Now how can I keep only the first two rows and delete only the last two rows?

Note- this is how I read the file from my local machine:
string[] lines = File.ReadAllLines(@"C:\Users\admin\Desktop\COMMANDS.dat");

I have tried something like this but I think it's not so "efficient"

string text = File.ReadAllText(@"C:\Users\admin\Desktop\COMMANDS.dat");
text = text.Replace(lines[2], "");
text = text.Replace(lines[3], ""); 
File.WriteAllText(@"C:\Users\admin\Desktop\COMMANDS.dat", text);

So this actually does the job, it replaces the lines by string with an empty character but when I take a look at the file, I don't want to have 4 lines there, even though 2 of them are real strings and the other two are just empty lines... Can I manage to do this in another way?

LeotrimR
  • 62
  • 6
  • Does this answer your question? [Delete specific line from a text file?](https://stackoverflow.com/questions/1245243/delete-specific-line-from-a-text-file) – gunr2171 Jan 20 '22 at 12:58
  • Use a list instead an array – J.Salas Jan 20 '22 at 12:59
  • 2
    @J.Salas `ReadAllText` returns an array, so not sure how turning that into a list would help. The point is to not have to read the entire file contents into memory. – gunr2171 Jan 20 '22 at 13:00
  • var list = new List(File.ReadAllLines(@"C:\Users\admin\Desktop\COMMANDS.dat")); then you can delete elements over the list and use a .toarray for the write – J.Salas Jan 20 '22 at 13:05
  • @gunr2171 `ReadAllText` returns a string, not an array. We don't know the amount of data here and for a known limited number of lines (a few thousand) reading all of them would be the more "efficient" solution. – Christoph Lütjen Jan 20 '22 at 14:02
  • I was thinking ReadAllLines. My point still stands. If you feel the term "efficient" is vague, opinionated, and missing details, vote to close. – gunr2171 Jan 20 '22 at 14:06

2 Answers2

0

Try replacing the newline character with an empty string:

string text = File.ReadAllText(@"C:\Users\admin\Desktop\COMMANDS.dat");
text = text.Replace(lines[2], "").Remove(Environment.NewLine, "");
text = text.Replace(lines[3], "").Remove(Environment.NewLine , "");
File.WriteAllText(@"C:\Users\admin\Desktop\COMMANDS.dat", text);

If my answer is useful, please mark it as accepted, and upvote it.

0
    async Task Example()
    {
        var inputLines = await File.ReadAllLinesAsync("path/to/file.txt");
        var outputLines = inputLines.Where((l, i) => i < 2);
        await File.WriteAllLinesAsync("target/file.txt", outputLines);
    }

What it does

  • Read data but not as one string but as a collection of lines
  • Create a new collection containing only the lines you want in your output
  • Write the filtered lines

Notes:

  • This example is not optimized for memory usage (because we read all lines and for larger files, e.g. multiple GB, this will fail). See existing answers for memory optimized version) - but: It's totally fine to do it this way if you know you have just a few k lines. (and it's faster)
  • Try not to "modify" strings. This will always create a copy and needs a lot of memory.
  • In this "Linq style" (functional) approach, we should treat data as immutable. That means: we have one variable that represents the input file and one variable that represents the result. We use declarative Linq to describe how the output should look like. "output is input where the filter index < 2 matches" instead of "if xy remove line" in an imperative style.
Christoph Lütjen
  • 5,403
  • 2
  • 24
  • 33