Solved

Binary Replace in VB.NET

Posted on 2007-03-22
9
1,319 Views
Last Modified: 2012-08-13
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

0
Comment
Question by:carpbyte
  • 4
  • 4
9 Comments
 
LVL 11

Expert Comment

by:Babycorn-Starfish
ID: 18775996
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
 
LVL 34

Expert Comment

by:Sancler
ID: 18776175
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
 

Author Comment

by:carpbyte
ID: 18776208
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
 

Author Comment

by:carpbyte
ID: 18776219
Everything I saw that does a loop through an array was very slow...
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 34

Expert Comment

by:Sancler
ID: 18776288
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
 
LVL 34

Expert Comment

by:Sancler
ID: 18778213
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
 

Author Comment

by:carpbyte
ID: 18781711
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
 
LVL 34

Accepted Solution

by:
Sancler earned 125 total points
ID: 18783745
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
 

Author Comment

by:carpbyte
ID: 18783858
That did the trick.

Thanks.

Carp
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

705 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now