udfFileGetLastLines
str udfFileGetLastLines (str, int)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileGetLastLines (strFilename, intLines)
If intLines < 1 Then Return ""
intFileSize = FileSize (strFilename)
If !intFileSize Then Return ""

; Check for trailing @LF and adjust lines to read.
hdlBB = BinaryAlloc (1)
If BinaryReadEx (hdlBB, 0, strFilename, intFileSize - 1, 1)
   If (BinaryPeekStr (hdlBB, 0, 1) != @LF) Then intLines = intLines - 1
EndIf
hdlBB = BinaryFree (hdlBB)

; Read file from backward into buffer chunks of n byte size
; and move the line pointer for each @LF backward into the file.
intBBsize = 8192 ; 8 kB buffer, but modify buffer size to your needs.
hdlBB = BinaryAlloc (intBBsize)
intChunkOffset = (intFileSize / intBBsize) * intBBsize
While @TRUE
   If intChunkOffset < 0 Then Break
   If BinaryReadEx (hdlBB, 0, strFilename, intChunkOffset, intBBsize)
      intOffsetLF = BinaryEodGet (hdlBB)
      While @TRUE
         If intLines < 0 Then Break
         intOffsetLF = BinaryIndexEx (hdlBB, intOffsetLF - 1, @LF, @BACKSCAN, @TRUE)
         If intOffsetLF < 0 Then Break
         intLines = intLines - 1
      EndWhile
   EndIf
   If intLines < 0 Then Break
   intChunkOffset = intChunkOffset - intBBsize
EndWhile
hdlBB = BinaryFree (hdlBB)

; Get all the last lines into one buffer and peek the whole string.
If intOffsetLF < 0 Then intOffsetLF = 0
If intChunkOffset < 0 Then intChunkOffset = 0
intOffsetLF = intOffsetLF + intChunkOffset
If intOffsetLF Then intOffsetLF = intOffsetLF + 1
strLines = ""
intBBsize = intFileSize - intOffsetLF
If intBBsize > 0
   hdlBB = BinaryAlloc (intBBsize)
   If BinaryReadEx (hdlBB, 0, strFilename, intOffsetLF, intBBsize)
      ; Move eod pointer before trailing @LF and trailing @CR.
      If BinaryPeekStr (hdlBB, intBBsize-1, 1) == @LF Then intBBsize = intBBsize - 1
      If BinaryPeekStr (hdlBB, intBBsize-1, 1) == @CR Then intBBsize = intBBsize - 1
      strLines = BinaryPeekStr (hdlBB, 0, intBBsize)
   EndIf
   hdlBB = BinaryFree (hdlBB)
EndIf
Return strLines
;..........................................................................................................................................
; This UDF "udfFileReadLastLines" returns a string that contains the last n lines of a textfile.
;
; Detlev Dalitz.20030528.20090428.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

strFilename = IntControl (1004, 0, 0, 0, 0) ; We use this file as test input.
intLines = 11
strLines = udfFileGetLastLines (strFilename, intLines)
strLines = StrReplace (strLines, @CRLF, @LF)
strLines = StrReplace (strLines, @CR, "")
strMsgTitle = "Demo: udfFileGetLastLines (strFilename, intLines)"
strMsgText  = StrCat ('Filename = "', strFilename, '"', @LF, 'Last ', intLines, ' Lines ==>', @LF, strLines, @LF, '<==')
Message (strMsgTitle, strMsgText)

Exit
;------------------------------------------------------------------------------------------------------------------------------------------