Search code examples
powershellcarriage-return

Read the first line of the file including carriage return line feed


What I am trying to achieve here is to read the first only line of a text file to the string and capture carriage return line feed (or any other non printable characters) altogether as well, but neither without reading full contents of the file nor the second line (if present) and at this point I am not sure how to achieve this using PowerShell. Please note, the script is going to be dealing with the files of size ranging up to 30GB in size, so reading all the file contents into the memory is clearly no option for me (timewise as well).

Using the below I am able to read in the first line only but CR/LF characters get trimmed at the end of the line:

   $File = New-Object System.IO.StreamReader -Arg $PathFull
   $Header = $File.ReadLine()
   $File.Close()

I can also get the first line using:

$Header = (Get-Content -Path $PathFull -Head 1)

but, as expected Get-Content reads each line as a string into collection of objects and CR/LF characters here also get lost at the first line as well.

The only way I was able to read in the CR/LF characters was using the -Raw key with Get-Content commandlet, but that didn't solve my original problem as it read the whole contents of the file first and using both -Raw and -Head keys at the same time is not allowed.

Please note, that adding these characters back to the string manually after reading the line with something like:

$Header = $Header + "$([Char]13)$([Char]10)"

is not an option for me as well as my goal is purely to determine whether the line I read was correctly delimited with either combination of CR/LF, CR only or LF only characters and I have no knowledge of this before reading the actual line.

Any help on this topic is much appreciated.


Solution

  • Use the Read() method to read each character one at a time until you encounter either a carriage return or a line feed:

    $reader = New-Object System.IO.StreamReader D:\file.txt    
    do{
        $c = $reader.Read()
        $result = if($c -eq 13){
            if(-not $reader.EndOfStream -and 10 -eq $reader.Read()){
                'CRLF'
            }else{
                'CR'
            }
        }elseif($c -eq 10){
            'LF'
        }
    }until($result)
    $reader.Dispose()
    
    return $result