Search code examples
c#filestreamwriter

Index of the line in StreamWriter


I'm using StreamWriter to write into file, but I need the index of line I'm writing to.

int i;
using (StreamWriter s = new StreamWriter("myfilename",true) {   
    i= s.Index(); //or something that works.
    s.WriteLine("text");    
}

My only idea is to read the whole file and count the lines. Any better solution?


Solution

  • The definition of a line

    The definition of a line index and more specifically a line in a file is denoted by the \n character. Typically (and on Windows moreso) this can be preceded by the carriage return \r character too, but not required and not typically present on Linux or Mac.

    Correct Solution

    So what you are asking is for the line index at the current position basically means you are asking for the number of \n present before the current position in the file you are writing to, which seems to be the end (appending to the file), so you can think of it as how many lines are in the file.

    You can read the stream and count these, with consideration for your machines RAM and to not just read in the entire file into memory. So this would be safe to use on very large files.

    // File to read/write
    var filePath = @"C:\Users\luke\Desktop\test.txt";
    
    // Write a file with 3 lines
    File.WriteAllLines(filePath, 
        new[] {
            "line 1",
            "line 2",
            "line 3",
        });
    
    // Get newline character
    byte newLine = (byte)'\n';
    
    // Create read buffer
    var buffer = new char[1024];
    
    // Keep track of amount of data read
    var read = 0;
    
    // Keep track of the number of lines
    var numberOfLines = 0;
    
    // Read the file
    using (var streamReader = new StreamReader(filePath))
    {
        do
        {
            // Read the next chunk
            read = streamReader.ReadBlock(buffer, 0, buffer.Length);
    
            // If no data read...
            if (read == 0)
                // We are done
                break;
    
            // We read some data, so go through each character... 
            for (var i = 0; i < read; i++)
                // If the character is \n
                if (buffer[i] == newLine)
                    // We found a line
                    numberOfLines++;
        }
        while (read > 0);
    }
    

    The lazy solution

    If your files are not that large (large being dependant on your intended machine/device RAM and program as a whole) and you want to just read the entire file into memory (so into your programs RAM) you can do a one liner:

    var numberOfLines = File.ReadAllLines(filePath).Length;