Would it be better to have ten streams open and read them each from the beginning, or could I have one big stream with all the data, and jump around however I want at no cost?
You might want to look into
filemapping, at least for Windows (you'd have to research how it's done on the other OSes).
You're placing a memory 'window' of a particular size (64K) over a 'map' of the file and then operating on the contents of that memory 'window', moving it back and forth, etc, but it's the fastest way to read/write files in Windows, since it's carried out by the Virtual Memory Manager's low level disk access functions, rather than the high level file operations you'd normally have access to:
... - file
[ ] - 64K window
....[...]...................
Although you tell it to map the whole file, it only places 64K into memory at a time, the optimum 'data chunk' size on Windows. Here's a PB example (apologies)...
Procedure ReadMappedFile (f$)
; Used to pass 64-bit number to MapViewOfFile in two parts...
Structure HiLo
hi.l
lo.l
EndStructure
; Filemapping REQUIRES use of system's most efficient memory chunk size...
GetSystemInfo_ (info.SYSTEM_INFO)
chunk = info\dwAllocationGranularity ; Usually 64K / 65536
view.HiLo
; How many times to read 'chunk' bytes in For/Next loop...
fsize.q = FileSize (f$)
loops.q = fsize / chunk
remainder = fsize % chunk
If remainder
loops = loops + 1 ; Extra loop for remainder if less than 'chunk' bytes
EndIf
; Get file handle...
file = CreateFile_ (@f$, #GENERIC_READ, 0, #Null, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL | #FILE_FLAG_SEQUENTIAL_SCAN, #Null)
If (file <> #INVALID_HANDLE_VALUE)
; Create file map, defaulting to the whole file size...
mapped = CreateFileMapping_ (file, #Null, #PAGE_READONLY, 0, 0, #Null)
If mapped
; Read 'chunk' bytes (65536 generally) however many times are needed...
For byte = 0 To loops - 1
; Fill HiLo structure with current filemap offset...
PokeQ (@view, byte * chunk)
; Hack for remainder on last loop if smaller than 'chunk' bytes...
mapbytes = chunk
If byte = loops - 1
If remainder
mapbytes = remainder
EndIf
EndIf
; Position 'chunk' sized view into filemap...
mapview = MapViewOfFile_ (mapped, #FILE_MAP_READ, view\lo, view\hi, mapbytes)
If mapview
; ------------------------------------------------------
; Process 'mapbytes' bytes from mapview address here, eg...
; ------------------------------------------------------
For offset = 0 To mapbytes - 1
asc = PeekB (mapview + offset)
; Debug Chr (asc)
Next
; ------------------------------------------------------
; End of mapview processing
; ------------------------------------------------------
; Free map view...
UnmapViewOfFile_ (mapview)
EndIf
Next
; Close filemapping handle...
CloseHandle_ (mapped)
EndIf
; Close file handle...
CloseHandle_ (file)
EndIf
EndProcedure
; ReadMappedFile ("test.txt")
For writing, you'd change the constants passed to CreateFile, CreateFileMapping, MapViewOfFile, etc.