3

Is it possible to loop for each line in a file and check how it ends (LF / CRLF):

using(StreamReader sr = new StreamReader("TestFile.txt")) 
{
    string line;
    while ((line = sr.ReadLine()) != null) 
    {
        if (line.contain("\r\n") 
        {
            Console.WriteLine("CRLF");
        }
        else if (line.contain("\n") 
        {
            Console.WriteLine("LF");
        }
    }
}
juharr
  • 31,741
  • 4
  • 58
  • 93
user2848242
  • 177
  • 1
  • 11
  • 6
    `ReadLine` is going to remove the line terminator so you'd need to do Read and check for line terminating characters. – juharr Jan 22 '21 at 15:38
  • could you give me an example plz – user2848242 Jan 22 '21 at 15:38
  • How would you want it to handle it if the file contains both types of line endings? – Jacob Lockard Jan 22 '21 at 15:43
  • I will put it in a log file, each line whith its end – user2848242 Jan 22 '21 at 15:45
  • @user2848242 what's the actual problem? `ReadLine` can handle both cases, so you don't need to know what the line endings are. If you don't want to read lines, only detect the endings and expect all lines to have the same ending you can read characters one-by-one until you encounter the first `\r` or \n`. If you expect mixed endings you'll have to keep reading until you've encountered at least one case of each line ending. You may have to load the entire file this way to ensure there are no mixed endings – Panagiotis Kanavos Jan 22 '21 at 15:46
  • 1
    @user2848242 `I will put it in a log file, each line whith its end` that would break the log file's lines – Panagiotis Kanavos Jan 22 '21 at 15:47
  • Does this help? https://stackoverflow.com/questions/3015611/determine-what-line-ending-is-used-in-a-text-file – Avigrail Jan 22 '21 at 15:47
  • @PanagiotisKanavos, no i will have line 1 - CRLF , Line 2- LF, just the index of the line – user2848242 Jan 22 '21 at 15:52

2 Answers2

2

You'll have to use Read to get each character and check for the line terminators. You'll also have to keep track if you've seen a carriage return so you'll know if you're dealing with a CRLF or just a LF when you see a line feed. And you'll have to check for a trailing CR after the loop is done.

using(StreamReader sr = new StreamReader("TestFile.txt")) 
{
    bool returnSeen = false;
    while (sr.Peek() >= 0) 
    {
        char c = sr.Read();
        if (c == '\n')
        {
            Console.WriteLine(returnSeen ? "CRLF" : "LF");
        }
        else if(returnSeen)
        {
            Console.WriteLine("CR");
        }

        returnSeen = c == '\r';
    }

    if(returnSeen) Console.WriteLine("CR");
}

Note you can construct the lines from the characters you read and you can change this to use the overload of Read that read into a buffer and search the result for the line terminators for better performance.

juharr
  • 31,741
  • 4
  • 58
  • 93
0

you can this code:

private const char CR = '\r';  
private const char LF = '\n';  
private const char NULL = (char)0;

public static long CountLines(Stream stream)  
{
    //Ensure.NotNull(stream, nameof(stream));

    var lineCount = 0L;

    var byteBuffer = new byte[1024 * 1024];
    var prevChar = NULL;
    var pendingTermination = false;

    int bytesRead;
    while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
    {
        for (var i = 0; i < bytesRead; i++)
        {
            var currentChar = (char)byteBuffer[i];

            if (currentChar == NULL) { continue; }
            if (currentChar == CR || currentChar == LF)
            {
                if (prevChar == CR && currentChar == LF) { continue; }

                lineCount++;
                pendingTermination = false;
            }
            else
            {
                if (!pendingTermination)
                {
                    pendingTermination = true;
                }
            }
            prevChar = currentChar;
        }
    }

    if (pendingTermination) { lineCount++; }
    return lineCount;
}
Meysam Asadi
  • 6,438
  • 3
  • 7
  • 17