Re: VB6 - Huge (>2GB) File I/O Class
Btw, it's possible to just use Shell32 provided file streams from VB6 as COM based IUnknown references so that on pressing End button/statement the reference is Release'd by the IDE and the file handle gets closed automagically without extra hacks.
The streams work with >2GB large (and even huge) files *and* support long filenames (can be above MAX_PATH) in Unicode (can be in arabic) on all versions of Windows as an added bonus.
The impl code is pretty short as well w/ no additional typelibs (or thunks) and in client code one can just keep a reference to the actual stream instead of to the HugeBinaryFile instance so not much different.
cheers,
</wqw>
Re: VB6 - Huge (>2GB) File I/O Class
Quote:
Originally Posted by
wqweto
Btw, it's possible to just use
Shell32 provided file streams from VB6 as COM based IUnknown references so that on pressing End button/statement the reference is Release'd by the IDE and the file handle gets closed automagically without extra hacks.
The streams work with >2GB large (and even huge) files *and* support long filenames (can be above MAX_PATH) in Unicode (can be in arabic) on all versions of Windows as an added bonus.
The impl code is pretty short as well w/ no additional typelibs (or thunks) and in client code one can just keep a reference to the actual stream instead of to the HugeBinaryFile instance so not much different.
cheers,
</wqw>
Your code very useful! Thanks for sharing.
Btw, I test huge file copy with this module. below 4GB, arbitrary buffer size is ok, but above 4GB files only 8192 and it's multiples buffers(like 64k) are ok. arbitrary buffer size, destination file is smaller than original file. Wired.
(test code)
Option Explicit
Private Sub Form_Load()
On Error GoTo ErrorHandler
Dim fileSize As Double
Dim filePath As String
Dim filePath1 As String
Dim fileStreamRead As stdole.IUnknown
Dim fileStreamWrite As stdole.IUnknown
Dim dataRead() As Byte
Dim bytesToRead As Long
Dim bytesRead As Long
' ?? ?? ?? ??
filePath = "C:\1_ftp\1_ftp.zip"
' ??? ?? ?? ??
filePath1 = "C:\1_ftp\1_ftp6.zip"
' ?? ??? ?? ??? ??
Set fileStreamRead = StreamOpenFile(filePath)
'-----------------------------
' ?? ?? ???
fileSize = StreamGetSize(fileStreamRead)
Debug.Print "?? ??: "; fileSize; " ???"
'----------------------------
End
' ??? ??? ?? ??? ??
Set fileStreamWrite = StreamOpenFile(filePath1, True)
' ?? ??? 64KB? ??
bytesToRead = 8192 '65536 ' 64KB
' ??? ??? ?? ??
Do While Not StreamEOF(fileStreamRead)
dataRead = StreamReadBytes(fileStreamRead, bytesToRead)
bytesRead = UBound(dataRead) + 1
If bytesRead > 0 Then
StreamWriteBytes fileStreamWrite, dataRead
End If
Loop
' ??? ??
Set fileStreamRead = Nothing
Set fileStreamWrite = Nothing
Debug.Print "?? ?? ??"
Exit Sub
ErrorHandler:
Debug.Print "?? ??: "; Err.Description
' ??? ?? (?? ?? ???)
If Not fileStreamRead Is Nothing Then Set fileStreamRead = Nothing
If Not fileStreamWrite Is Nothing Then Set fileStreamWrite = Nothing
End Sub
Re: VB6 - Huge (>2GB) File I/O Class
Weird indeed!
I can repro this bug here. After reading past 4GB position when 3000 bytes are requested to be read the file position is shifted forward 4096 bytes but still only 3000 bytes are read. This seems to be a bug of IStream implementation of SHCreateStreamOnFile which I cannot find anywhere else being reported which is even weirder.
A workaround would be to count total bytes read and use StreamSeekAbsolute after each StreamReadBytes to correct current input position or (more effective) use I/O buffer with size in multiple of 4KB which is what almost everyone else does and the reason this problem has not been observed in real applications and reported already.
Nowadays a buffer of 1MB (and above) is probably performing the best for reading in a loop scenarios.
cheers,
</wqw>
Re: VB6 - Huge (>2GB) File I/O Class
Quote:
Originally Posted by
wqweto
Weird indeed!
I can repro this bug here. After reading past 4GB position when 3000 bytes are requested to be read the file position is shifted forward 4096 bytes but still only 3000 bytes are read. This seems to be a bug of IStream implementation of SHCreateStreamOnFile which I cannot find anywhere else being reported which is even weirder.
A workaround would be to count total bytes read and use StreamSeekAbsolute after each StreamReadBytes to correct current input position or (more effective) use I/O buffer with size in multiple of 4KB which is what almost everyone else does and the reason this problem has not been observed in real applications and reported already.
Nowadays a buffer of 1MB (and above) is probably performing the best for reading in a loop scenarios.
cheers,
</wqw>
Thanks for the reply. It's ok for me as you said I'll use 8192bytes for buffer. I think this code is the best and simple for >2G file accessing. (I like VB6 and has been using for a long time and I know your name. Every time searching vb6 I can see your posts/reply. Thanks again for sharing :)