|
Post by nsbrown on Apr 27, 2022 12:00:32 GMT -5
Hello LB programmer's,
I need to make an array that contains each line in a file that changes each time. Once the file can contain 10 lines and once over 300,000 lines. I do not want to just allocate a lot of memory in an array for a few lines. So my current solution right now is to read the file twice.
First read the number of rows, next dim the array according to the number of rows counted, And finally read the file again - this time write down the data into the array. A bit cumbersome and takes quite a bit of processing time, when it comes to large files.
Is there a better way? Is there a function that returns the number of lines in the file?
Here is an example:
TotalLines=0
open "c:\test.txt" for input as #1
while eof(#1)>-1
TotalLines=TotalLines+1
line input #1,temp$
wend
close #1
dim FileInfo$(TotalLine)
open "c:\test.txt" for input as #1
for a=1 to TotalLine
line input #1,FileInfo$(a)
next a
close #1
Regards, Sharon Brown
|
|
|
Post by tsh73 on Apr 27, 2022 13:58:44 GMT -5
(As far as I know)
No
If it would, it would still have to read whole file.
|
|
|
Post by Rod on Apr 27, 2022 14:25:44 GMT -5
Leave it all in the file? A file header can tell you how many records there are. But why bring it into an array. Use RAF or Binary to skip about the records without the necessity to load an Array.
|
|
|
Post by Walt Decker on Apr 27, 2022 17:17:41 GMT -5
Yes. Open the file for binary and read the whole file into a string. Parse the string for crlf and count the number of crlf pairs found. You can then dim an array to that count + 1 and parse it again to put the lines in the array. There is a plethora of string parsing functions in the "Share Your Snippets" threads.
Alternatively, I think the DIR.DLL function found in the "API and DLL" thread has a function to return the number of crlf delimited lines in a file.
|
|
|
Post by nsbrown on Apr 28, 2022 1:27:37 GMT -5
Thank you all I really appreciate it
|
|
|
Post by Walt Decker on Apr 30, 2022 12:38:46 GMT -5
Someone might find this useful:
' 'STREAM_000._BAS OPEN "FlRecords" FOR DLL AS #FLR
BUTTON #STM.LOAD, "LOAD FILE", LOAD.FL, UL, 5, 5, 70, 20 OPEN "STREAM" FOR WINDOW AS #STM PRINT #STM, "TRAPCLOSE CLOSE.STM"
WAIT
'-------------------------------- '--------------------------------
SUB CLOSE.STM Stmhndl$ CLOSE #FLR CLOSE #STM END END SUB
'----------------------------------- '-----------------------------------
SUB LOAD.FL BtnHndl$
ER.NONE = 0 '<--- ERROR CODES ER.NOT.FOUND = 1 ER.NO.RECORDS = 2 ER.UNKNOWN = 4
STRUCT tRecs, _ Fpath$ AS PTR, _ '<--- OUT: Path to file; RETURN: pointer to _ 'file string if StreamOut > zero Frecords AS LONG, _ '<--- # of crlf records in file Fsize AS LONG, _ '<--- # of bytes in file StreamOut AS USHORT '<--- zero = do not return file contents ' > zero return file contents
FlPath$ = DefaultDir$ + "\" + "STREAM_000._BAS"
tRecs.Fpath$.struct = FlPath$ tRecs.StreamOut.struct = 1
ErCode = 0 CALLDLL #FLR, "FN_Stream", tRecs AS STRUCT, ErCode AS SHORT IF ErCode = ER.NONE THEN PRINT "# RECORDS = "; tRecs.Frecords.struct PRINT PRINT "# BYTES = "; tRecs.Fsize.struct PRINT PRINT "CONTENTS = " PRINT FlPath$ = WINSTRING(tRecs.Fpath$.struct) PRINT FlPath$ END IF END SUB
'----------------------------------------- '-----------------------------------------
FUNCTION FN.PARSE(StrIn$, NumRecs, Delim$) '############################################## ' CAN USE THIS FUNCTION TO PLACE RECORDS OR ' PORTIONS OF RECORDS BASED ON THE VALUE OF ' "Delim$" INTO AN ARRAY '##############################################
DlmPos = 0 DlmSiz = 0 DlmCnt = -1
Dlm$ = Delim$ IF Dlm$ = "" THEN Dlm$ = ","
DlmSiz = LEN(Dlm$)
REDIM AryOut$(NumRecs)
[DO.AGAIN]
DlmPos = INSTR(StrIn$, Dlm$)
IF DlmPos = 0 THEN GOTO [EXIT.DO]
DlmCnt = DlmCnt + 1
IF DlmCnt > NumRecs THEN GOTO [EXIT.DO]
AryOut$(DlmCnt) = LEFT$(StrIn$, DlmPos - 1)
StrIn$ = MID$(StrIn$, DlmPos + DlmSize) GOTO [DO.AGAIN]
[EXIT.DO] IF StrIn$ <> "" THEN DlmCnt = DlmCnt + 1 AryOut$(DlmCnt) = StrIn$ END IF FN.PARSE = DlmCnt END FUNCTION '
|
|