Possible to read line by line a txt file with binary mode?
Tks.
Printable View
Possible to read line by line a txt file with binary mode?
Tks.
Yes, it's possible. The ReadBytes routine below does that. but it is going
to be slow compared to other methods.
If the lines in the file were all the same length it would be fairly easy.
However, the fastest method would be as shown in the Form_Load routine
below, reading the entire file into memory & splitting on vbcrlf.
Code:Option Explicit
Private Sub Form_Load()
Dim a() As String
Dim Txt As String
Dim i As Long
Txt = ReadFileBinary("C:\test.txt")
a = Split(Txt, vbCrLf)
For i = 0 To UBound(a)
If LenB(a(i)) Then
Debug.Print a(i)
End If
Next
ReadBytes
End Sub
Private Sub ReadBytes()
Dim b As Byte
Dim s As String
Dim hFile As Long
hFile = FreeFile
Open "C:\test.txt" For Binary As hFile
Do While Not EOF(hFile)
Get #hFile, , b 'read a byte at a time
If b = 13 Then 'vbcr
Get #hFile, , b 'eat the vblf
Debug.Print s 'store result & clear
s = vbNullString
Else
s = s & ChrW$(b)
End If
Loop
Close hFile
End Sub
'function to read the entire file into a string
Private Function ReadFileBinary(ByVal sFilePath As String) As String
Dim hFile As Long
hFile = FreeFile
Open sFilePath For Binary As #hFile
ReadFileBinary = String$(LOF(hFile), vbNullChar)
Get #hFile, , ReadFileBinary
Close #hFile
End Function
Break it into small chunks, I suggest 64kb as it seems to work particularly well.
The only complication is that lines get chopped. One solution is to start reading the next chunk from the offset of the last line delimiter encountered in the previous chunk.
I'm pretty tired to be honest, two days off in the last 40 days and that was two weeks ago.
In order not to waste time what are these lines you are reading being used for? You have said you don't want them all in one go so would a bunch of lines at a time be useful? I thinking a function that returns a bunch of lines which has a ByRef offset parameter that increments with each call.
An example that needs a bit more work...Code:Private Sub ProcessLines(Filename As String)
Dim FF As Integer, offset As Long, lines() As String
offset = 1
On Error GoTo EH
FF = FreeFile
Open Filename For Binary As #FF
Do While Not EOF(FF)
lines = GetNextBunchOfLines(FF, offset)
'Do something with bunch of lines
Loop
Close #FF
Exit Sub
EH:
'tell user of file error here
End Sub
Private Function GetNextBunchOfLines(fileNumAsBinary As Integer, ByRef offset As Long) As String()
Dim position As Long, length As Long
Const CHUNK As Long = &H10000
Dim stringBuffer As String
length = Min(CHUNK, LOF(fileNumAsBinary) - offset)
stringBuffer = String(length, vbNullChar)
Get #fileNumAsBinary, offset, stringBuffer
position = InStrRev(stringBuffer, vbLf)
If position <> -1 Then
offset = offset + position
GetNextBunchOfLines = Split(Left$(stringBuffer, position - 2), vbCrLf)
Else 'No vbCrLf found in 64kb
'Do something!!
End If
End Function
Private Function Min(a As Long, b As Long) As Long
If a < b Then Min = a Else Min = b
End Function