Reputation: 1300
I am trying to read a binary file and edit the data and then write the file back as a new file. Reading the file, and Writing the file is not a problem... it works fine.
But, any way I try to modify the binary data, I get an error: "VBScript runtime error: Type mismatch"
As an example, I am reading a file and modifying the 3rd byte to be an "@" (at-sign).
Option Explicit
Const ADTYPEBINARY = 1
Const ADSAVECREATEOVERWRITE = 2
Dim gstrInputFileName
Dim gstrOutputFileName
Dim gobjBinaryInputStream
Dim gobjBinaryOutputStream
Dim gbytearrayReadBinaryFile
gstrInputFileName = "some-binary-file.bin"
gstrOutputFileName = "output-binary-filename.bin"
WScript.Echo "Reading the file data"
Set gobjBinaryInputStream = CreateObject("ADODB.Stream")
gobjBinaryInputStream.Type = ADTYPEBINARY
gobjBinaryInputStream.Open
gobjBinaryInputStream.LoadFromFile gstrInputFileName
gbytearrayReadBinaryFile = gobjBinaryInputStream.Read
gobjBinaryInputStream.Close
Set gobjBinaryInputStream = Nothing
WScript.Echo "Modifying the file data"
' These all fail... "Type mismatch"
'' pwwqbytearrayReadBinaryFile(3) = &H40
'' pwwqbytearrayReadBinaryFile(3) = ChrB(65)
'' pwwqbytearrayReadBinaryFile(3) = Chr(65)
'' pwwqbytearrayReadBinaryFile(3) = AscB("@")
'' pwwqbytearrayReadBinaryFile(3) = Asc("@")
'' pwwqbytearrayReadBinaryFile(3) = "@"
'' pwwqbytearrayReadBinaryFile(3) = 65
WScript.Echo "Writing the file data"
Set gobjBinaryOutputStream = CreateObject("ADODB.Stream")
gobjBinaryOutputStream.Type = ADTYPEBINARY
gobjBinaryOutputStream.Open
gobjBinaryOutputStream.Write gbytearrayReadBinaryFile
gobjBinaryOutputStream.SaveToFile gstrOutputFileName, ADSAVECREATEOVERWRITE
gobjBinaryOutputStream.Close
Set gobjBinaryOutputStream = Nothing
WScript.Echo
WScript.Quit
Upvotes: 1
Views: 5634
Reputation: 38765
The problem is: binary streams deliver and expect byte arrays (TypeName "Byte()", VarType 8209) which can't be manipulated with VBScript. A solution for your sample task is:
' read first byte from input, write it to output
gobjBinaryOutputStream.Write gobjBinaryInputStream.Read(1)
' skip second byte from input
gobjBinaryInputStream.Position = gobjBinaryInputStream.Position + 1
' use .NET to get a byte array containing '@' and write it to output
gobjBinaryOutputStream.Write CreateObject("System.Text.ASCIIEncoding").GetBytes_4("@")
' copy rest of input to output
gobjBinaryOutputStream.Write gobjBinaryInputStream.Read
Obviously, this approach does not scale for real world tasks; so you should consider using a language that supports binary data natively.
Upvotes: 2