NOL
Posted: Thu Jan 20, 2011 3:54 am
If you need the number of lines in a file, the only native way in PB (that I know of) is to go through it with ReadString until you reach the EOF, counting up one each time.
But if you know that every line in the file will be of a certain length, you can use this code which is MUCH faster:
I've tried it on many different files and it's counted correctly every time. I know that code like this may be obvious to many people - I'm hoping there are other PB users out there as gormless as me who will benefit from this post!
This macro version is even faster:
... but it will cause a crash if the FileSize is zero (division by zero forbidden), so you really have to use the procedure version.
You could use this next version, but it's not so easy to integrate into your code:
As for getting the line count when you DON'T know how long each line will be... I've written this but it's slower than using While/ReadString/Wend:
On my machine, running that 1000 times takes 703ms, whereas the ReadString method only takes 141ms. Are there any faster ways?
Again, I know the FixedLengthNOL procedure may be obvious, but no doubt somebody, somewhere, will use it.
Code: Select all
Procedure.f NOL(fn.s)
f = ReadFile(#PB_Any,fn)
If f
While Not Eof(f)
ReadString(f)
n+1
Wend
CloseFile(f)
ProcedureReturn n
EndIf
ProcedureReturn 0
EndProcedure
number_of_lines = NOL(filename$,10)
Code: Select all
Procedure.i FixedLengthNOL(fn.s,linelength)
fs = FileSize(fn)
If fs>0
ProcedureReturn Round(fs/(linelength+2),#PB_Round_Up)
EndIf
ProcedureReturn 0
EndProcedure
number_of_lines = FixedLengthNOL(filename$,10)
This macro version is even faster:
Code: Select all
Macro FixedLengthNOL(fn,linelength)
Round(FileSize(fn)/(linelength+2),#PB_Round_Up)
EndMacro
number_of_lines = FixedLengthNOL(filename$,10)
You could use this next version, but it's not so easy to integrate into your code:
Code: Select all
Macro FixedLengthNOL(fn,linelength,var)
var = 0
fs = FileSize(fn)
If fs>0
var = Round(fs/(linelength+2),#PB_Round_Up)
EndIf
EndMacro
FixedLengthNOL(filename$,10,number_of_lines)
As for getting the line count when you DON'T know how long each line will be... I've written this but it's slower than using While/ReadString/Wend:
Code: Select all
Procedure.i NOL(fn.s)
f = ReadFile(#PB_Any,fn)
If f
loaf = Lof(f)
If loaf<1
CloseFile(f)
ProcedureReturn 0
EndIf
*mem = AllocateMemory(loaf)
ReadData(f,*mem,loaf)
CloseFile(f)
For a = 1 To loaf
this.i = PeekA(*mem+a-1)
If this = 13
lines+1
EndIf
Next a
EndIf
ProcedureReturn lines
EndProcedure
Again, I know the FixedLengthNOL procedure may be obvious, but no doubt somebody, somewhere, will use it.
