-1

I'm trying to remove lines that are in between two different lines. Currently, I have:

string s = "";
String path = @"C:\TextFile";
StreamWriter sw = new StreamWriter(path, true);
StreamReader sr = new StreamReader(path, true);

s = sr.ReadLine();

if (s=="#Start")
{
    while (s != "#End")
    {
        sw.WriteLine(s);
        //need something here to overwrite existing data with s not just add s
    }
}  

sr.Close();
sw.Close();  

The content of my text file looks like this:

#Start
facebook.com
google.com
youtube.com
#End     

I tried to follow Efficient way to delete a line from a text file however it deletes any file containing a certain character, whereas there are other lines outside of the range containing .com that I don't want to remove

I want to delete all the contents in between start and end so after the method runs the remains of the text file is

#Start
#End
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Explorex
  • 547
  • 6
  • 13
  • The problem you have here is that you expect only the first line to contain `#Start` and then you only write until you reach `#End`. Then you just stop. – ProgrammingLlama Oct 24 '18 at 02:11
  • 1
    @John: No, it's worse than that - the poster only reads the first line, and then loops continually writing that same line out until infinity (or the disk fills up), because the loop never reads another line. – Ken White Oct 24 '18 at 02:14
  • @Ken You're quite right.I missed that. Eep. – ProgrammingLlama Oct 24 '18 at 02:15
  • I have no idea what you're actually asking here. Your code does nothing (see my previous comment to John) to try to delete anything. You've shown your current file, but not explained what you're expecting to do to that file. What line specifically do you want to delete? All of them between `#Start` and `#End`? Just one line? Please [edit] and show what you're trying to end up with when you're finished. – Ken White Oct 24 '18 at 02:18
  • It's always a good idea to use stream objects inside `using` blocks. `using(StreamWriter sw = new StreamWriter(path, true)){..}` – Sisir Oct 24 '18 at 03:17
  • If you find fault with every answer provided, please make your question clearer. – ProgrammingLlama Oct 25 '18 at 05:07

3 Answers3

0

You have two problems:

  1. You're only reading the first line, and then you're using that one value everywhere. Clearly if s == "#Start", it can't also satisfy the condition s == "#End", etc.
  2. Even if you were reading each line, you expect that after #End there will be no more data - you don't loop through the rest of the lines, you just stop writing. Based on your question, I think you want to write all lines from the file and only change those between #Start and #End.

-

Perhaps a constant loop as below would be better?:

string s;
bool inRewriteBlock = false;
while ((s = sr.ReadLine()) != null)
{
    if (s == "#Start")
    {
        inRewriteBlock = true;
    }
    else if (s == "#End")
    {
        inRewriteBlock = false;
    }
    else if (inRewriteBlock)
    {
        sw.WriteLine(s);
        //need something here to overwrite existing data with s not just add s
    }
    else
    {
        sw.WriteLine(s);
    }
}

By default, the code will output every line it reads verbatim. However, if it reads #Start it will enter a special mode (inRewriteBlock == true) where you can rewrite those lines however you want. Once it reaches #End it will transition back into the default mode (inRewriteBlock == false).

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • All I'm trying to do is remove everything in between #Start and #End. I am not concerned about anything else in the txt file. I just need to entirely remove everything in between, and with what I read you can't just remove, you need to overwrite the current characters. – Explorex Oct 25 '18 at 02:14
  • "I am not concerned about anything else in the txt file." - so you don't want to retain those lines in the file when you re-write it? You only want to save the lines between `#Start` and `#End`? – ProgrammingLlama Oct 25 '18 at 02:20
  • No, I have a method that writes in between those lines when called, however I'm struggling with removing the part in between the Start and End I've written when I call a method to remove everything in between. Text outside the start and end boundaries are irrelevant. – Explorex Oct 25 '18 at 03:13
  • "Text outside the start and end boundaries are irrelevant" - not if you want to keep them in the file. I give up. – ProgrammingLlama Oct 25 '18 at 03:33
  • I don't think you realise what you're doing in the code. You're reading a file and writing it in another file. You really should care about the stuff outside `#Start` and `#End`. Anyway, if you leave the `else if (inRewriteBlock)` empty this should work for you. It will read the original file and write everything except whatever is between `#Start` and `#End`. It will probably also include `#Start` and `#End` so you should put a `sw.WriteLine(s);` line after changing `inRewriteBlock`. Hope this helps. – ikerbera Oct 30 '18 at 14:42
0

You should check and rewrite every thing between #Start and #End instead of file is start with "#Start" only.

You can try this:

            //Read all text lines first
        string[] readText = File.ReadAllLines(path);

        //Open the text file to write
        var oStream = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.Read);
        StreamWriter sw = new System.IO.StreamWriter(oStream);


        bool inRewriteBlock = false;

        foreach (var s in readText)
        {
            if (s.Trim() == "#Start")
            {
                inRewriteBlock = true;
                sw.WriteLine(s);
            }
            else if (s.Trim() == "#End")
            {
                inRewriteBlock = false;
                sw.WriteLine(s);
            }
            else if (inRewriteBlock)
            {
                //REWRITE DATA HERE (IN THIS CASE IS DELETE LINE THEN DO NOTHING)
            }
            else
            {
                sw.WriteLine(s);
            }
        }

        sw.Close();
Nhan Phan
  • 1,262
  • 1
  • 14
  • 32
  • What is the tmpPath though? As they both cant simultaneously open the same path, how do I read and write at the same time? – Explorex Oct 25 '18 at 02:15
  • Hi, If you want to open and overwrite the text file from beginning, then you can read all text lines, and open file to overwrite it. I updated my answer based on that. You can take a look. – Nhan Phan Oct 25 '18 at 03:07
  • That removes everything from my file. I only want to remove in between start and end – Explorex Oct 25 '18 at 03:25
  • Really?I tested 3 cases from my side, and all of them worked well. Only text between #start and #end were removed – Nhan Phan Oct 25 '18 at 03:28
  • If its of any value I'm editing the Windows Hosts File. – Explorex Oct 26 '18 at 04:03
0

You can simply do this: (This assumes file can be stored in memory)

string path = @"C:\\Users\\test\\Desktop\\Test.txt";

List<string> fileData = File.ReadAllLines(path).ToList();
// File.ReadAllLines(path).ToList().Select(y => y.Trim()).ToArray().ToList(); will remove all trailing/preceding spaces in data
int startsWith = fileData.IndexOf("#Start");
int endsWith = fileData.IndexOf("#End");

if(startsWith != -1 && endsWith != -1)
  fileData.RemoveRange(startsWith+1, endsWith-1);

File.WriteAllLines("C:\\Test\\Test1.txt", fileData.ToArray());

It doesnt account for special scenarios like startsWith is at the end of the file with no endswith.

Gauravsa
  • 6,330
  • 2
  • 21
  • 30
  • I keep receiving this error: System.ArgumentException: 'Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.' – Explorex Oct 25 '18 at 02:04
  • I tried the code. it seems to work. you may have to check for #Start and #End doesnt have a space after them. Maybe use trim. See edited code above. – Gauravsa Oct 25 '18 at 02:33
  • can you check values for startsWith and endsWith and if they are not -1.. – Gauravsa Oct 25 '18 at 02:36
  • can you share ur input – Gauravsa Oct 25 '18 at 03:17