Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Mix mode input of a binary open file Question!
#1
I get the strangest ideas now and then.  By the experts here everyone might get ideas about my thought.  - OR - I will be shot down in flames.

Normally I would use binary open to read in a text file.  Much faster than "open" using input mode.  My thoughts on the matter, I would like to use a mix mode of getting the data.  I would normally open with binary mode start reading using "line input #1,d$".  But switch to "input #1,n1,n2,n3,n4" at some point.  Such as content of my file:


#   Comments
#   Comments
#   Comments
#   Comments
#
#eoc
1,2,3,4
5,6,7,8
9,10,11,12
999999,0,0,0
# more comments
#   Comments
#   Comments
#   Comments
#   Comments
#
#eoc
13,14,15,16
17,18,19,20

Note the line "#eoc".  This would be my trigger point to switch to "input #1,n1,n2,n3,n4" to get the remaining data.  An after thought at this point and I changed my file now as I am typing this out.  If I can switch mix input modes.  Can I go back to "line input" and again go back to "input" modes ?  The other trigger point is the 999999 value in first position.

I can see this as a possibility since binary input has a pointer to the file opened.  To where the next read of file takes place.  The input request only specifics how much input happens and where to stop.

Thanks for any answers.
BTW, if you are a United States member.  Why are you reading my comments.  GO GET STUFFED!!!.
By Turkey.

[Image: pizza-turkey.jpg]
Reply
#2
Easy Peasy two-minute exercise in creating a HybridInput routine for you.   Smile

Code: (Select All)
Open "Z:/test.txt" For Input As #1
Do
    Print HybridInput$(1)
    Sleep
Loop Until EOF(1)

Function HybridInput$ (file)
    Static As Long ReadWholeLine, Init
    StartPos = Seek(file)
    If ReadWholeLine Then
        Line Input #1, dta$
        If Left$(_Trim$(dta$), 1) = "#" Then HybridInput$ = dta$: Exit Function
        ReadWholeLine = 0 'we are no longer reading the whole line
        Seek file, StartPos
    End If
    Input #1, dta$
    If Left$(_Trim$(dta$), 1) = "#" Then ReadWholeLine = -1
    HybridInput$ = dta$
End Function

Note that if you want to do this with BINARY input mode, you'd basically do the same, but you'd have to change the INPUT section to simply parse that dta$ form StartPos, looking for the comma, and take that segment to be your input.  Then SEEK to the proper position (StartPos + length of the dta$ segment you called the answer +1 for the comma after), and you'd be primed to ust continue on with no problems whatsoever.

BINARY doesn't support INPUT (one of these days, I've always said I was going to expand it so it could...), so you'll just need to parse your dta$, get the proper input, and then move the file pointer back to the proper spot to pick up from on the next read for data.


Attached Files
.txt   test.txt (Size: 215 bytes / Downloads: 11)
Reply
#3
Nice work, Steve. It depends on the programmer's approach, I realized. While you are providing a way to do it, I was looking for reasons not to do it Smile

It will work via binary access as you write here, but it won't work via Input and a file opened for reading, because some characters control the behavior of the input command in Open for Input mode.

The following program shows how binary text can confuse the Input command when reading a binary file.

Code: (Select All)

For a = 0 To 255
    f$ = Chr$(a) + f$
Next a

ff = FreeFile
Open "binTest" For Binary As ff
Put ff, , f$
Close ff

ff = FreeFile
_ControlChr Off 'not for operations in file, just for printing...
Open "binTest" For Input As ff
Dim b As String
Do Until EOF(ff)
    Input #ff, b$ 'or try LINE INPUT, returned string is not returned in full lenght
    Sleep
    Print b$, Len(b$)
Loop
Close ff


Reply
#4
(11-28-2024, 01:44 PM)SMcNeill Wrote: Easy Peasy two-minute exercise in creating a HybridInput routine for you.   Smile

Code: (Select All)
Open "Z:/test.txt" For Input As #1
Do
    Print HybridInput$(1)
    Sleep
Loop Until EOF(1)

Function HybridInput$ (file)
    Static As Long ReadWholeLine, Init
    StartPos = Seek(file)
    If ReadWholeLine Then
        Line Input #1, dta$
        If Left$(_Trim$(dta$), 1) = "#" Then HybridInput$ = dta$: Exit Function
        ReadWholeLine = 0 'we are no longer reading the whole line
        Seek file, StartPos
    End If
    Input #1, dta$
    If Left$(_Trim$(dta$), 1) = "#" Then ReadWholeLine = -1
    HybridInput$ = dta$
End Function

Note that if you want to do this with BINARY input mode, you'd basically do the same, but you'd have to change the INPUT section to simply parse that dta$ form StartPos, looking for the comma, and take that segment to be your input.  Then SEEK to the proper position (StartPos + length of the dta$ segment you called the answer +1 for the comma after), and you'd be primed to ust continue on with no problems whatsoever.

BINARY doesn't support INPUT (one of these days, I've always said I was going to expand it so it could...), so you'll just need to parse your dta$, get the proper input, and then move the file pointer back to the proper spot to pick up from on the next read for data.
This could work for me and anybody else.  I will just convert string to number when needed.  Side bonus:  Didn't know "\" and "/" interchangeable with a pathname.
Thanks for the "+" answer.
Reply
#5
(11-28-2024, 02:02 PM)Petr Wrote: Nice work, Steve. It depends on the programmer's approach, I realized. While you are providing a way to do it, I was looking for reasons not to do it Smile

It will work via binary access as you write here, but it won't work via Input and a file opened for reading, because some characters control the behavior of the input command in Open for Input mode.

The following program shows how binary text can confuse the Input command when reading a binary file.

Code: (Select All)

For a = 0 To 255
    f$ = Chr$(a) + f$
Next a

ff = FreeFile
Open "binTest" For Binary As ff
Put ff, , f$
Close ff

ff = FreeFile
_ControlChr Off 'not for operations in file, just for printing...
Open "binTest" For Input As ff
Dim b As String
Do Until EOF(ff)
    Input #ff, b$ 'or try LINE INPUT, returned string is not returned in full lenght
    Sleep
    Print b$, Len(b$)
Loop
Close ff

It's not supposed to.  If you need to read a full binary range of characters (from 0 to 255 ASCII), you can't use INPUT.  There are various old-school control codes embedded into INPUT, which are necessary for us to honor so that old QB45 programs can still compile and run the same as always with files written using those rules.

CHR$(26) is one of those terminal characters, if I remember correctly (it's CTRL-Z) and if basically counts much the same as an EOF marker.  With it you used to be able to write a data file like so:

Red Bus, 1, 2, 3, 4, CHR$(26), Blue Bus, 1, 2, 3, 4, CHR$(26)....

Now, you could OPEN that file and read to EOF, and you'd only read to the CHR$(26) character.  INPUT would basically return
Red Bus
1
2
3
4

IF you wanted the second file of data, you would SEEK #1, proper_position and then do the INPUT so you get
Blue Bus
1
2
3
4
(CHR$(26) as EOF marker)

Think of it as an old-school way of packing multiple text files together into one single file.  You had your own individual data streams, all separated by that control character.

Reading a file as BINARY, you don't have those control characters.  You'd have to account for them yourself, if you program made use of them or not...

But they're the reason why you're seeing breaks when using INPUT to read a BINARY file.   INPUT was never made to read the whole 256 ASCII character range.  It was made more for text input, with control characters embedded into the stream to help organize it into better and more manageable data.  Wink
Reply
#6
+1 Thanks for the detailed description, I'm a little smarter again  Big Grin


Reply




Users browsing this thread: 5 Guest(s)