Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

A Simple Set of Buffered File Output Routines

I/O

A Simple Set of Buffered File Output Routines

by  logiclrd  Posted    (Edited  )
[tt]
[color #000080]SUB[/color] selectFileToBuffer(fileNumber%, bufferSize&)
[color #000080]SHARED[/color] bufferedFileNumber%, bufferedFileBuffer$, bufferedFileBufferOffset%

[color #000080]IF[/color] bufferedFileBufferOffset% [color #000080]THEN[/color] flushBuffer

bufferedFileNumber% = fileNumber%
bufferedFileBuffer$ = ""
bufferedFileBuffer$ = [color #000080]SPACE$[/color](bufferSize&)
bufferedFileBufferOffset% = 0
[color #000080]END SUB

SUB[/color] writeBufferedChar(character$)
[color #000080]SHARED[/color] bufferedFileNumber%, bufferedFileBuffer$, bufferedFileBufferOffset%

bufferedFileBufferOffset% = bufferedFileBufferOffset% + 1
[color #000080]MID$[/color](bufferedFileBuffer$, bufferedFileBufferOffset%, 1) = character$
[color #000080]IF[/color] bufferedFileBufferOffset% = [color #000080]LEN[/color](bufferedFileBuffer$) [color #000080]THEN
PUT[/color] #bufferedFileNumber%, , bufferedFileBuffer$
bufferedFileOffset% = 0
[color #000080]END IF
END SUB

SUB[/color] writeBufferedByte(asciiValue%)
writeBufferedChar [color #000080]CHR$[/color](asciiValue%)
[color #000080]END SUB

SUB[/color] writeBufferedString(stringToWrite$)
[color #000080]SHARED[/color] bufferedFileNumber%, bufferedFileBuffer$, bufferedFileBufferOffset%

a$ = stringToWrite$ [color #008000]' Local copy[/color]
bytesLeft% = [color #000080]LEN[/color](a$)
[color #000080]DO WHILE[/color] bytesLeft%
bytesLeftInBuffer% = [color #000080]LEN[/color](bufferedFileBuffer$) - bufferedFileBufferOffset%
[color #000080]IF[/color] bytesLeftInBuffer% > bytesLeft [color #000080]THEN EXIT DO

MID$[/color](bufferedFileBuffer$, bufferedFileBufferOffset% + 1, bytesLeftInBuffer%) = [color #000080]LEFT$[/color](a$, bytesLeftInBuffer%)
[color #000080]PUT[/color] #bufferedFileNumber%, , bufferedFileBuffer$

a$ = [color #000080]MID$[/color](a$, bytesLeftInBuffer% + 1)
bytesLeft% = bytesLeft% - bytesLeftInBuffer%
bufferedFileBufferOffset% = 0
[color #000080]LOOP
MID$[/color](bufferedFileBuffer$, bufferedFileBufferOffset% + 1, bytesLeft%) = [color #000080]LEFT$[/color](a$, bytesLeft%)
bufferedFileBufferOffset% = bufferedFileBufferOffset% + bytesLeft%
[color #000080]END SUB

SUB[/color] flushBuffer()
[color #000080]SHARED[/color] bufferedFileNumber%, bufferedFileBuffer$, bufferedFileBufferOffset%

[color #000080]IF[/color] bufferedFileBufferOffset% [color #000080]THEN[/color]
usedBuffer$ = [color #000080]LEFT$[/color](bufferedFileBuffer$, bufferedFileBufferOffset%)
[color #000080]PUT[/color] #bufferedFileNumber%, , usedBuffer$
bufferedFileBufferOffset% = 0
[color #000080]END IF
END SUB[/color]
[/tt]
To start using these [tt][color #000080]SUB[/color][/tt]s, call [tt][color #000080]SUB[/color] selectFileToBuffer[/tt] and pass it a file number opened by [tt][color #000080]OPEN[/color][/tt] in [tt][color #000080]BINARY[/color][/tt] mode, as well as a buffer size (4096 or 8192 should be about optimal -- smaller buffers cause degraded performance, but QB has trouble with strings larger than 8 kilobytes (it can do them, but the string space gets all fragmented and messy)).

Then, to output bytes or strings, call the appropriate output function (the routines remember the file number automatically). When you are done, call [tt][color #000080]SUB[/color] flushBuffer[/tt] before closing your file, otherwise some data will not be written to file and will be lost.

You can switch from your own output to this buffered output at any time (provided the file was opened [tt][color #000080]FOR BINARY[/color][/tt]), and you can switch back to your own output code at any time by calling [tt][color #000080]SUB[/color] flushBuffer[/tt], however doing so very often would reduce the effectiveness of the buffer and degrade performance. When switching back from your routines to the buffered routines after the buffered routines have already been in use, you do not need to call [tt][color #000080]SUB[/color] selectFileToBuffer[/tt] again, as all the settings are remembered and the buffer is in a proper state from [tt][color #000080]SUB[/color] flushBuffer[/tt]. It should also be safe to switch the buffer from one file to another (it automatically flushes the buffer), but the same performance issue applies.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top