How to read and write a binary file.

Posted on 2000-03-30
Last Modified: 2013-11-13
My problem is this: I have a custom socket server application written in Java. I am writting the client app in VB6. I would like to read a binary file (MS Word Document) from the client into a byte array and simply write it out to the socket using the Winsock control. This seemed simple in the beginning. I started experimenting by reading a file into a byte array and writting it back to the hard drive with a different name. The code is as follows:
  Dim buffer(1024) As Byte
  Open "c:\logo1024.jpg" For Binary Access Read As #1
  Open "c:\logo1024_new.jpg" For Binary Access Write As #2
  Get #1, , buffer
  Do While Not EOF(1)
    Put #2, , buffer
    Get #1, , buffer
  Close #1
  Close #2
This only works if I use a single byte as my buffer and not a byte array. Which is very slow! This seems to add one byte to the file for each "Put". You will also probably notice with this logic the last 'partially filled' buffer contents are not written to the new file.  Again, even if I force it to write the last bit, it results in a file larger than the original.

Is there a way to do this? Help?

I also tried getting the file size and making my buffer exactly that size. This resulted in a file that was one byte larger than the original.

Thanks in advance.
Question by:kkennedy65
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
  • 2
  • +2

Expert Comment

ID: 2671995
Try this:

Dim buffer() As Byte

  Open App.Path + "\trailer.txt" For Binary Access Read As #1
  Open App.Path + "\new_trailer.txt" For Binary Access Write As #2
  ReDim buffer(1 To LOF(1))
  Get #1, , buffer
  Put #2, , buffer

  Close #1
  Close #2

Expert Comment

ID: 2672004
Try this:

Dim buffer() As Byte

  Open App.Path + "\trailer.txt" For Binary Access Read As #1
  Open App.Path + "\new_trailer.txt" For Binary Access Write As #2
  ReDim buffer(1 To LOF(1))
  Get #1, , buffer
  Put #2, , buffer

  Close #1
  Close #2

Expert Comment

ID: 2672011
Sorry for the double post.  Hey what gives - I'm reading a question post time later than my comments.
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now


Expert Comment

ID: 2672020
If is a ms word document, then you can't read it as binary file. It is file in a structured storage file. You got to use structure storage APIs to do the rad and write the files. SO you can use APIs to read the file and send it through socket.

For more info on how to read structure storage file check out

Expert Comment

ID: 2672046

I tried this with a word doc after reading the post and it works fine with VB5.  As far as I know a VB binary file read/write will work on any file.

Expert Comment

ID: 2672062
Binary file reading should work with any file. But if you know the format, you can extract what exactly u want to transfer.

Expert Comment

ID: 2672095

No arguement with your comment but why complicate things if you want to deal with the whole file?

Expert Comment

ID: 2672164

Forgot to mention the source of the problem you were having.  Unless you declare a specific array lower bound (with "Option Base"), it will default to 0.
Your "Dim buffer(1024) As Byte" is actually (0 to 1024), a 1025 byte array.
LVL 14

Accepted Solution

wsh2 earned 100 total points
ID: 2672717
Thumbs up on bhamilto's solution.. <smile>.

One caveat though.. with very large files you may want to thunk your way through the binary file rather than read it all at once. With large reads.. once physical memory gets used up.. Windows swaps the excess out to disk and in effect you end up reading / writing it twice.. <sigh>. Below is an example of thunking.. set the BUFFER_SIZE constant to whatever you think best (10000 works nice) and with large files, you should see better performance.

<----- Code Begin ----->

Private Function xFile_Copy _
(ByVal strFileGet As String, ByVal strFilePut As String) _
As Long

   Const BUFFER_SIZE = 10000 ' Set to whatever you think best
   On Error GoTo ErrGet
   Dim intGet As Integer
   intGet = FreeFile
   Open strFileGet For Binary Access Read As intGet
   On Error GoTo ErrPut
   Dim intPut As Integer
   intPut = FreeFile
   Open strFilePut For Binary Access Write As intPut
   On Error GoTo ErrCopy
   Dim bytBuffer() As Byte
   ReDim bytBuffer(1 To BUFFER_SIZE)
   Dim lngThunk As Long
   Do Until lngThunk >= LOF(intGet)
      If lngThunk + UBound(bytBuffer) > LOF(intGet) _
         ReDim bytBuffer(1 To LOF(intGet) - lngThunk)
      End If
      lngThunk = lngThunk + UBound(bytBuffer)
      Get intGet, , bytBuffer()
      Put intPut, , bytBuffer()
   xFile_Copy = lngThunk
   Close intGet
   Close intPut
   GoTo Tag999

   MsgBox (strFileGet & " ERROR")
   GoTo Tag999

   MsgBox (strFilePut & " ERROR")
   Close intGet
   GoTo Tag999

   MsgBox ("ERROR Copying " & strFileGet & " To " & strFilePut)
   Close intGet
   Close intPut
   Kill strFilePut
   GoTo Tag999

   On Error GoTo 0

End Function

<----- Code End ----->

Author Comment

ID: 2673940
Thanks to all for your comments. Thanks bhamilto for all your input. I guess I've been working in Java too long and forgot how VB handles the initialization of arrays. I have to give the points to wsh2. Thanks wsh2 for the exact funtion I was looking for! This experts exchange really does work!

Author Comment

ID: 2673942
It was exactly what I was looking for.

Expert Comment

ID: 3410475
here's anotherway to read/write (copy)
it reads only 64k (max) at a time

Free = FreeFile
maxsel = FileLen("C:\file.exe")
Dim dat1 As String * 1: Dim dat2 As String * 2
Dim dat3 As String * 4: Dim dat4 As String * 8
Dim dat5 As String * 16: Dim dat6 As String * 32
Dim dat7 As String * 64: Dim dat8 As String * 128
Dim dat9 As String * 256: Dim dat10 As String * 512
Dim dat11 As String * 1024: Dim dat12 As String * 2048
Dim dat13 As String * 4096: Dim dat14 As String * 8192
Dim dat15 As String * 16384: Dim dat16 As String * 32768
Dim dat17 As String * 65526
Dim dat
  Open "C:\filewrite.exe" For Output As #2
  Open "C:\fileread.exe" For Binary Access Read Lock Read As #1
    orgmaxsel = maxsel
    If maxsel = 1 Then
      Get #1, , dat1
      maxsel = maxsel - 1
      dat = dat1
    ElseIf maxsel >= 2 And maxsel < 4 Then
      Get #1, , dat2
      maxsel = maxsel - 2
      dat = dat2
    ElseIf maxsel >= 4 And maxsel < 8 Then
      Get #1, , dat3
      maxsel = maxsel - 4
      dat = dat3
    ElseIf maxsel >= 8 And maxsel < 16 Then
      Get #1, , dat4
      maxsel = maxsel - 8
      dat = dat4
    ElseIf maxsel >= 16 And maxsel < 32 Then
      Get #1, , dat5
      maxsel = maxsel - 16
      dat = dat5
    ElseIf maxsel >= 32 And maxsel < 64 Then
      Get #1, , dat6
      maxsel = maxsel - 32
      dat = dat6
    ElseIf maxsel >= 64 And maxsel < 128 Then
      Get #1, , dat7
      maxsel = maxsel - 64
      dat = dat7
    ElseIf maxsel >= 128 And maxsel < 256 Then
      Get #1, , dat8
      maxsel = maxsel - 128
      dat = dat8
    ElseIf maxsel >= 256 And maxsel < 512 Then
      Get #1, , dat9
      maxsel = maxsel - 256
      dat = dat9
    ElseIf maxsel >= 512 And maxsel < 1024 Then
      Get #1, , dat10
      maxsel = maxsel - 512
      dat = dat10
    ElseIf maxsel >= 1024 And maxsel < 2048 Then
      Get #1, , dat11
      maxsel = maxsel - 1024
      dat = dat11
    ElseIf maxsel >= 2048 And maxsel < 4096 Then
      Get #1, , dat12
      maxsel = maxsel - 2048
      dat = dat12
    ElseIf maxsel >= 4096 And maxsel < 8192 Then
      Get #1, , dat13
      maxsel = maxsel - 4096
      dat = dat13
    ElseIf maxsel >= 8192 And maxsel < 16384 Then
      Get #1, , dat14
      maxsel = maxsel - 8192
      dat = dat14
    ElseIf maxsel >= 16384 And maxsel < 32768 Then
      Get #1, , dat15
      maxsel = maxsel - 16384
      dat = dat15
    ElseIf maxsel >= 32768 And maxsel < 65526 Then
      Get #1, , dat16
      maxsel = maxsel - 32768
      dat = dat16
    ElseIf maxsel >= 65526 Then
      Get #1, , dat17
      maxsel = maxsel - 65526
      dat = dat17
    End If
    Me.Caption = Format(maxsel, "000,000,000") & " bytes remaining"
    Print #2, dat
  Loop Until maxsel = 0

Close #1
Close #2
dat = ""

Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you haven’t already, I encourage you to read the first article ( in my series to gain a basic foundation of R and R Studio.  You will also find the …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This video teaches viewers about errors in exception handling.
In a recent question ( here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

628 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question