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.
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.


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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
using web browser with BING 40 149
What language/protocol is the Angular Chat? 2 110
Link failure 16 91
Excel Macro: Correct Macro that creates tabs for each "AccountSku" 4 50
How to remove superseded packages in windows w60 or w61 installation media (.wim) or online system to prevent unnecessary space. w60 means Windows Vista or Windows Server 2008. w61 means Windows 7 or Windows Server 2008 R2. There are various …
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

734 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