Question

For a project that I am doing, one of the things that I must do is delete the first X lines of a plaintext file. I'm saying X because I will need to do this routine multiple times and each time, the lines to delete will be different, but they will always start from the beginning, delete the first X and then output the results to the same file.

I am thinking about doing something like this, which I pieced together from other tutorials and examples that I read:

String line = null;

String tempFile = Path.GetTempFileName();
String filePath = openFileDialog.FileName;

int line_number = 0;
int lines_to_delete = 25;

using (StreamReader reader = new StreamReader(originalFile)) {
    using (StreamWriter writer = new StreamWriter(tempFile)) {
        while ((line = reader.ReadLine()) != null) {
            line_number++;

            if (line_number <= lines_to_delete)
                continue;

            writer.WriteLine(line);
        }
    }
}

if (File.Exists(tempFile)) {
    File.Delete(originalFile);
    File.Move(tempFile, originalFile);
}

But I don't know if this would work because of small stuff like line numbers starting at line 0 or whatnot... also, I don't know if it is good code in terms of efficiency and form.

Thanks a bunch.

Was it helpful?

Solution

It's OK, and doesn't look it would have the off-by-one problems you fear. However a leaner approach would be afforded by two separate loops -- one to just count the first X lines from the input file (and do nothing else), a separate one to just copy the other lines from input to output. I.e., instead of your single while loop, have...:

    while ((line = reader.ReadLine()) != null) {
        line_number++;

        if (line_number > lines_to_delete)
            break;
    }

    while ((line = reader.ReadLine()) != null) {
        writer.WriteLine(line);
    }

OTHER TIPS

I like it short...

File.WriteAllLines(
    fileName,
    File.ReadAllLines(fileName).Skip(numberLinesToSkip).ToArray());

I like your approach, I see nothing wrong with it. If you know for certain they are small files then the other suggestions may be a little less code if that matters to you.

A slightly less verbose version of what you already have:

using (StreamReader reader = new StreamReader(originalFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
    while(lines_to_delete-- > 0)
        reader.ReadLine();
    while ((line = reader.ReadLine()) != null)
        writer.WriteLine(line);
}

You could read the file into an array of lines, ignore the first few elements, and write the rest back.

The downside to this approach is that it will consume the size of the file in memory. Your approach (although pretty unreadable, no offence) doesn't have this memory problem. Although if the files are not too large, there shouldn't be a reason to worry about memory usage.

Example:

string[] lines = System.IO.File.ReadAllLines("YourFile.txt").Skip(10).ToArray();
System.IO.File.WriteAllLines("OutFile.txt", lines);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top