Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

How to read and write a binary file.

Posted on 2000-03-30
12
Medium Priority
?
317 Views
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
  Loop
 
  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.
0
Comment
Question by:kkennedy65
  • 6
  • 2
  • 2
  • +2
12 Comments
 
LVL 2

Expert Comment

by:bhamilto
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
0
 
LVL 2

Expert Comment

by:bhamilto
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
0
 
LVL 2

Expert Comment

by:bhamilto
ID: 2672011
Sorry for the double post.  Hey what gives - I'm reading a question post time later than my comments.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 6

Expert Comment

by:VBGuru
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
http://www.geocities.com/SiliconValley/Foothills/9940/
0
 
LVL 2

Expert Comment

by:bhamilto
ID: 2672046
VBGuru

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.
0
 
LVL 6

Expert Comment

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

Expert Comment

by:bhamilto
ID: 2672095
VBGuru

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

Expert Comment

by:bhamilto
ID: 2672164
kkennedy65

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.
0
 
LVL 14

Accepted Solution

by:
wsh2 earned 400 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) _
      Then
         ReDim bytBuffer(1 To LOF(intGet) - lngThunk)
      End If
      lngThunk = lngThunk + UBound(bytBuffer)
      Get intGet, , bytBuffer()
      Put intPut, , bytBuffer()
   Loop
   
   xFile_Copy = lngThunk
   Close intGet
   Close intPut
   GoTo Tag999

ErrGet:
   MsgBox (strFileGet & " ERROR")
   GoTo Tag999

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

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

Tag999:
   On Error GoTo 0

End Function

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

Author Comment

by:kkennedy65
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!
0
 

Author Comment

by:kkennedy65
ID: 2673942
It was exactly what I was looking for.
0
 

Expert Comment

by:newmembername
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
   
  Do
    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
    DoEvents
   
    Me.Caption = Format(maxsel, "000,000,000") & " bytes remaining"
    Print #2, dat
 
  Loop Until maxsel = 0

Close #1
Close #2
 
dat = ""
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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 (http://www.experts-exchange.com/articles/18680/An-Introduction-to-R-Programming-and-R-Studio.html) in my series to gain a basic foundation of R and R Studio.  You will also find the …
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Suggested Courses

782 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