Simon Canning
Simon Canning

Reputation: 215

Read/Write binary files

I have this code which works well:

Public Function LoadBinaryFile(strFilename As String) As Byte()
    Using fsSource As FileStream = New FileStream(strFilename, FileMode.Open, FileAccess.Read)
        ' Read the source file into a byte array.
        Dim bytes() As Byte = New Byte((fsSource.Length) - 1) {}
        Dim numBytesToRead As Integer = CType(fsSource.Length, Integer)
        Dim numBytesRead As Integer = 0

        'tsProgressBar.Minimum = 0
        'tsProgressBar.Maximum = numBytesToRead

        While (numBytesToRead > 0)
            ' Read may return anything from 0 to numBytesToRead.
            Dim n As Integer = fsSource.Read(bytes, numBytesRead, _
                numBytesToRead)
            ' Break when the end of the file is reached.
            If (n = 0) Then
                Exit While
            End If
            numBytesRead = (numBytesRead + n)
            numBytesToRead = (numBytesToRead - n)

            'tsProgressBar.Value = numBytesRead

        End While
        numBytesToRead = bytes.Length

        Return bytes

    End Using
End Function

And I have this code to save the file which also works well:

Public Function SaveBinaryFile(strFilename As String, bytesToWrite() As Byte) As Boolean
    Using fsNew As FileStream = New FileStream(strFilename, FileMode.Create, FileAccess.Write)
        fsNew.Write(bytesToWrite, 0, bytesToWrite.Length)
    End Using
End Function

What I am after is some help to modify the SaveBinaryFile function to implement a progress bar.

Final:

OK, I have written the function myself. Here it is:

    Public Function ReadBinaryFile(strFilename As String) As Byte()
    Dim position As Integer = 0
    Dim bufferSize As Integer = 4096
    Dim bytes() As Byte

    'frmMain.tsProgressBar.Value = 0

    Using fsOpen As FileStream = New FileStream(strFilename, FileMode.Open)
        redim bytes((fsOpen.Length) - 1)
        Do
            If (position + bufferSize) > fsOpen.Length Then
                fsOpen.Read(bytes, position, fsOpen.Length - position)
                Exit Do
            Else
                fsOpen.Read(bytes, position, bufferSize)
            End If
            'frmMain.tsProgressBar.Value = ((position / fsOpen.Length) * 100)
            'frmMain.tsProgressBar.Refresh()
            Application.DoEvents()
            position += bufferSize
        Loop
    End Using

    Return bytes

End Function

Upvotes: 1

Views: 8255

Answers (3)

user3412467
user3412467

Reputation: 1

'Or, if you are reading a file from a URL, here is a way to read the file into an array of bytes.

Dim WebRequest As Net.HttpWebRequest = Net.WebRequest.Create("http://mypage.abc.com/myfolder/MyFileName.xls")

Using WBinReader As BinaryReader = New BinaryReader(WRequest.GetResponse.GetResponseStream)
    Dim file_buffer() As Byte
    '10000000 is an arbitrary number, but File_Buffer will have no more 
    'elements than they number of bytes in the URL's file.
    file_buffer = WBinReader.ReadBytes(10000000) 
    file_bytes =UBound(buffer)+1
End Using

Brian Jasmer

Upvotes: -1

Matt
Matt

Reputation: 1796

I've never tried using the Async options on FileStream but there don't seem to be any event handlers.

I would break it down into a loop, you have the total amount of bytes to write so you could loop through writing 4k at a time, update your progress bar and continue the loop.

Public Sub SaveBinaryFile(strFilename As String, bytesToWrite() As Byte)
    Dim position As Integer = 0

    Using fsNew As FileStream = New FileStream(strFilename, FileMode.Create, FileAccess.Write)
        Do
            Dim intToCopy As Integer = Math.Min(4096, bytesToWrite.Length - position)
            Dim buffer(intToCopy - 1) As Byte
            Array.Copy(bytesToWrite, position, buffer, 0, intToCopy)
            fsNew.Write(buffer, 0, buffer.Length)
            ProgressBar1.Value = ((position / bytesToWrite.Length) * 100)
            Application.DoEvents()
            position += intToCopy
        Loop While position < bytesToWrite.Length
    End Using
End Sub

Upvotes: 1

Joshua
Joshua

Reputation: 43327

My.Computer.Filesystem.ReadAllBytes("filename") reads the entire file into a byte array.

My.Computer.Filesystem.WriteAllBytes("filename", bytes, false) writes it back.

Upvotes: 2

Related Questions