Binary Replace in VB.NET

OK I searched and have yet to find a suitable solution. Most of what I've found used a BinaryReader and was WAY too slow.

I'm trying to do a simple byte replace on a large binary file and not getting the speed I want.

In VB, I was able to use the following, so I'm wondering if it can be modified for .NET:

Open File For Binary As #ff
    FileString = String$(LOF(ff), Chr$(0))
    Get #ff, 1, FileString
    If FileString = "" Then Exit Function
    ReDim FileStringArray(1 To Len(FileString)) As Byte
    Call CopyMemory(FileStringArray(1), ByVal FileString, Len(FileString))
    For temp = 1 To Len(FileString)
        If FileStringArray(temp) = Asc(Chr(174)) Then 'replace through numeric Value
            FileStringArray(temp) = 13
        End If
        Next temp
    Call CopyMemory(ByVal FileString, FileStringArray(1), Len(FileString))
    ff1 = FreeFile
    Open tempfn$ For Binary As #ff1
    Put #ff1, 1, FileString
Close #ff

Any ideas?

Thanks.

Carp

carpbyteAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Babycorn-StarfishCommented:
Hi,

what type of solutions have you come across using the BinaryReader/Writers? just so i don't offer something you've already rejected.

Cheers

JW
0
SanclerCommented:
Try this

    Private Sub doReplace()
        Dim sr As New StreamReader("<yourInputFile>")
        Dim sInput As String = sr.ReadToEnd
        sr.Close()
        Dim sOutput As String = sInput.Replace(Chr(174), Chr(13))
        Dim sw As New StreamWriter("<yourOutputFile>")
        sw.Write(sOutput)
        sw.Flush()
        sw.Close()
    End Sub

You'll need

Imports System.IO

at the top of the file.

It's based on the thought that a binary file and a text file are essentially the same internally: it's just what reads and displays them that makes the difference.  So it reads the file as a String and uses [String].Replace with character codes.

The assumption "that a binary file and a text file are essentially the same internally" will not always be true for all practical purposes: e.g. Byte Order Markers and/or encoding can interfere with direct equivalence.  And I am not sure that I've got the replacement - 13 for 174 right.  But, if it works OK, I doubt you'll get it much faster.

Roger
0
carpbyteAuthor Commented:
The string reader doesn't appear to "read" non ascii characters - that's the problem.

For example the binary file I'm using has a Hex FE (254) as the first byte,  but if you read the first byte in the string it isn't that.

???
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

carpbyteAuthor Commented:
Everything I saw that does a loop through an array was very slow...
0
SanclerCommented:
Try this

Imports System.io
Public Class Form1

    Private Sub writefile()
        Dim sw As New StreamWriter("C:\Test\testfile.bin")
        Dim s As String = 0
        For i As Integer = 0 To 255
            s &= Chr(i)
        Next
        sw.Write(s)
        sw.Flush()
        sw.Close()
    End Sub

    Private Sub readfile()
        Dim sr As New StreamReader("C:\Test\testfile.bin")
        Dim s As String = sr.ReadToEnd
        sr.Close()
        For i As Integer = 0 To s.Length - 1
            Debug.WriteLine(Asc(s.Substring(i, 1)))
        Next
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        writefile()
        readfile()
    End Sub
End Class

What the streamreader can read and what any display mechanism will actually show are not necessarily the same.  The output for me from the above has an extra 48 at the start, but every other number from 0 to 255 shows OK.

Roger
0
SanclerCommented:
And I see now (in the cold light of morning) that ther reason for the "extra 48 at the start" is because I inadvertantly put

       Dim s As String = 0

instead of

       Dim s As String = ""

Roger
0
carpbyteAuthor Commented:
Nope.

Here's the problem I'm encountering - the binary file has the following characters I need to replace:

174  change to 13
254  change to 34
20    change to 124

ALL of these bytes exist in the file, however when loaded as a string neither the 174 or 254 are recognized. In fact, it appears they get stripped out completely, case in pont the very first char in the file is hex FE (254) but doing a debug on what SHOULD be the first char is actually returning the second.

I assume that by definition, using a string variable expects ONLY string and control bytes, thus they vanish.

I thnk the soultion involves creating a byte array, but looping through it is infinitely too slow.

???

Bizarre.

Thanks.
0
SanclerCommented:
As I said in my first post, "encoding can interfere with direct equivalence".  But I think we can get over that.  Here's a revised demo.  It creates the testfile with a binary writer.  It then reads it in with a binary reader.  But it then - successfully, at least in this demo - overcomes the encoding problems by a specific conversion from byte to string, does the replacements in the string, and then does a specific conversion back from string to byte.

Imports System.io
Public Class Form1

    Private Sub writefile()

        Dim ba(99) As Byte
        For i As Integer = 0 To 24
            ba(i * 4) = 96
            ba((i * 4) + 1) = 174
            ba((i * 4) + 2) = 20
            ba((i * 4) + 3) = 254
        Next

        Dim fs As New FileStream("C:\Test\testfile.bin", FileMode.Create)
        Dim w As New BinaryWriter(fs)
        w.Write(ba)
        w.Close()
        fs.Close()

    End Sub

    Private Sub readfile()

        Dim ba() As Byte
        Dim fs As New FileStream("C:\Test\testfile.bin", FileMode.Open, FileAccess.Read)
        Dim r As New BinaryReader(fs)
        ba = r.ReadBytes(100)
        r.Close()
        fs.Close()

        'convert byte array to string
        Dim s As String = System.Text.Encoding.Default.GetString(ba)
        'use string replace
        Dim t As String = s.Replace(Chr(254), Chr(34))
        t = t.Replace(Chr(174), Chr(13))
        t = t.Replace(Chr(20), Chr(124))
        'convert string back to byte array
        Dim bb() As Byte = System.Text.Encoding.Default.GetBytes(t)

        'test
        For i As Integer = 0 To s.Length - 1
            Debug.Write("Byte was " & ba(i) & ": ")
            Debug.WriteLine("byte is " & bb(i))
        Next

    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        writefile()
        readfile()
    End Sub
End Class

It seems to be working OK for me.

Roger
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
carpbyteAuthor Commented:
That did the trick.

Thanks.

Carp
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.