I'm trying to figure out how to read a section of bytes (Say 16) starting at a specific address, say 0x2050. I'd like to get the 16 bits output in hex values into a label.
I've been trying to figure out BinaryReader, and FileStreams but I'm not entirely sure what the difference is, or which one I should be using.
*I've seen a lot of threads mentioning file size could be an issue, and I'd like to point out that some files I'll be checking may be up to 4gb in size.
I've tried the following:
Dim bytes() As Byte = New Byte(OpenedFile.Length) {}
ListBox1.Items.Add(Conversion.Hex(OpenedFile.Read(bytes, &H2050, 6)))
But this simply writes 6 bytes to the file, and I'm not sure why. There is no output in the listbox.
How about something like the following?:
Sub Main()
Dim pos As Long = 8272
Dim requiredBytes As Integer = 2
Dim value(0 To requiredBytes - 1) As Byte
Using reader As New BinaryReader(File.Open("File.bin", FileMode.Open))
' Loop through length of file.
Dim fileLength As Long = reader.BaseStream.Length
Dim byteCount As Integer = 0
reader.BaseStream.Seek(pos, SeekOrigin.Begin)
While pos < fileLength And byteCount < requiredBytes
value(byteCount) = reader.ReadByte()
pos += 1
byteCount += 1
End While
End Using
Dim displayValue As String
displayValue = BitConverter.ToString(value)
End Sub
Related
In the PNG file format wikipedia page I saw this conversion of an image to a representation of the cost of bits per pixel (red=expensive, blue=cheap).
I was wondering if it is doable to program that kind of converter.
At the moment I don't know where to look up information about that so I decided to ask here with the little VB.NET code that I have made:
Dim MyBitmap As Bitmap = New Bitmap(filename:="C:\Original.png")
Dim MyBinaryReader As BinaryReader = New BinaryReader(File.OpenRead(path:="C:\Original.png"))
Dim MyBytes() As Byte = MyBinaryReader.ReadBytes(count:=Convert.ToInt32(File.OpenRead(path:="C:\Original.png").Length))
Dim MyString As String = ""
For Each MyByte As Byte In MyBytes
MyString = MyString & Convert.ToString(value:=MyByte, toBase:=2).PadLeft(totalWidth:=8, paddingChar:="0"c)
Next
Debug.WriteLine(MyString)
'For MyHeight As Integer = 0 To MyBitmap.Height - 1
' For MyHeight As Integer = 0 To MyBitmap.Height - 1
' MyBitmap.SetPixel(x:=MyWidth, y:=MyHeight, color:=MyBitmap.GetPixel(x:=MyWidth, y:=MyHeight))
' Next
'Next
'MyBitmap.Save(filename:="C:\New.png")
In my program, I collect bits of information on a massive scale, hundreds of thousands to millions of lines each. I am trying to limit each file I create to a certain size in order to be able to quickly open it and read the data. I am using a HashSet to collect all the data without duplicates.
Here's my code so far:
Dim Founds As HashSet(Of String)
Dim filename As String = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\Sorted_byKING\sorted" + Label4.Text + ".txt")
Using writer As New System.IO.StreamWriter(filename)
For Each line As String In Founds
writer.WriteLine(line)
Next
Label4.Text = Label4.Text + 1 'Increments sorted1.txt, sorted2.txt etc
End Using
So, my question is:
How do I go about saving, let's say 250,000 lines in a text file before moving to another one and adding the next 250,000?
First of all, do not use Labels to simply store values. You should use variables instead, that's what variables are for.
Another advice, always use Path.Combine to concatenate paths, that way you don't have to worry about if each part of the path ends with a separator character or not.
Now, to answer your question:
If you'd like to insert the text line by line, you can use something like:
Sub SplitAndWriteLineByLine()
Dim Founds As HashSet(Of String) 'Don't forget to initialize and fill your HashSet
Dim maxLinesPerFile As Integer = 250000
Dim fileNum As Integer = 0
Dim counter As Integer = 0
Dim filename As String = String.Empty
Dim writer As IO.StreamWriter = Nothing
For Each line As String In Founds
If counter Mod maxLinesPerFile = 0 Then
fileNum += 1
filename = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
$"Sorted_byKING\sorted{fileNum.ToString}.txt")
If writer IsNot Nothing Then writer.Close()
writer = New IO.StreamWriter(filename)
End If
writer.WriteLine(line)
counter += 1
Next
writer.Dispose()
End Sub
However, if you will be inserting the text from the HashSet as is, you probably don't need to write line by line, instead you can write each "bunch" of lines at once. You could use something like the following:
Sub SplitAndWriteAll()
Dim Founds As HashSet(Of String) 'Don't forget to initialize and fill your HashSet
Dim maxLinesPerFile As Integer = 250000
Dim fileNum As Integer = 0
Dim filename As String = String.Empty
For i = 0 To Founds.Count - 1 Step maxLinesPerFile
fileNum += 1
filename = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
$"Sorted_byKING\sorted{fileNum.ToString}.txt")
IO.File.WriteAllLines(filename, Founds.Skip(i).Take(maxLinesPerFile))
Next
End Sub
I'm trying to save text from a textbox as bytes. For example, The text from Textbox1 is "00001E0403" and I want to save them as bytes. What do I do then?
You can save as an array of bytes. Trying using this command:
System.Text.Encoding.Unicode.GetBytes(textbox1.text)
Try this:
Imports System.Globalization
Private Sub GetBytes()
Dim l As Integer = TextBox1.Text.Length - 1
Dim dataIndex As Integer = 0
Dim data(l \ 2) As Byte
For i As Integer = 0 To l Step 2
Dim hexChars As String = TextBox1.Text.Substring(i, Math.Min(2, TextBox1.Text.Length - i))
Dim dataByte As Byte
Byte.TryParse(hexChars, NumberStyles.HexNumber, Nothing, dataByte)
data(dataIndex) = dataByte
dataIndex += 1
Next i
End Sub
I am writing the vb.net to right padding the values. my code as follows:
Dim Ni As Byte() = { &HA6, &H02, &H01,....}
Dim Nca As Byte() = { &H12, &H00, &H02,....}
If (Ni.Length <= Nca.Length - 36) Then
Dim padLength As Integer = Nca.Length - 36 - Ni.Length
Dim padvalue As Byte() = {&HBB}
For Each w As Integer In padLength
Console.Write(Ni =Ni+ Ni.rigtPadding({&HBB}))
Next
End If
my code is not working. If Ni.Length<=Nca.Length-36, I need consist of the full Ni padded to the right with Nca-36-Ni bytes of hex value "&HBB". it is might be more than 1 "&HBB" need to be padded on the right side. and then I need the final result of Ni with the padding.
Ni is Issuer public key, Nca is CA public key ,the final result I want should be {&H6A, 02, 11, FF,....., BB,BB,BB}
Thank you very much for any help and comment.
Since you're using regular arrays this is relatively simple (but could be even simpler using a List(Of T)).
First you need to call Array.Resize() in order to increase the size of the array. Then you can use a regular For loop to fill the new space.
Dim prevLength As Integer = Ni.Length 'Store the previous length so we can start looping from it.
Array.Resize(Ni, Ni.Length + padLength) 'Take the original length and increase it by how much needs to be padded.
'Iterate from the beginning of the padding to the new end of the array.
For i = prevLength To Ni.Length - 1
Ni(i) = &HBB
Next
I also suggest you read up a little on how arrays work: Arrays in Visual Basic - Microsoft Docs.
You can manually resize NCI using Redim Preserve and set the padding character:
Dim Padding as Byte = &HBB
Dim Nca As Byte() = { &H12, &H00, &H02,....}
Dim Ni As Byte() = { &HA6, &H02, &H01,....}
Dim len = Nca.Length - 36
if (len > Ni.Length) Then
Redim Preserve Ni(len+1)
For i As Integer = len to Ni.Length-1
Ni(i) = Padding
Next
End if
Or you can use LINQ:
Dim Padding as Byte = &HBB
Dim Pad =Function(i) If(i < Nca.Length, Nca(i), padding)
Dim Nca As Byte() = { &H12, &H00, &H02,....}
Dim len as integer = Nca.Length - 36
if len > Ni.Length Then Ni = Enumerable.Range(0, len+1).Select(Pad).ToArray()
The way this file works is there is a null buffer, then a user check sum then a byte that gives you the user name letter count, then a byte for how many bytes to skip to the next user and a byte for which user file the user keeps their settings in.
the loop with the usersm variable in the IF statement sets up the whole file stream for extraction. However with almost the exact same code the else clause specifically the str.Read(xnl, 0, usn - 1) in the else code appears to be reading the very beginning of the file despite the position of the filestream being set earlier, anyone know whats happening here?
this is in vb2005
Private Sub readusersdata(ByVal userdatafile As String)
ListView1.BeginUpdate()
ListView1.Items.Clear()
Using snxl As IO.Stream = IO.File.Open(userdatafile, IO.FileMode.Open)
Using str As New IO.StreamReader(snxl)
str.BaseStream.Position = 4
Dim usersm As Integer = str.BaseStream.ReadByte()
Dim users As Integer = usersm
While users > 0
If usersm = users Then
Dim trailtouser As Integer = 0
str.BaseStream.Position = 6
Dim ust As Integer = str.BaseStream.ReadByte()
str.BaseStream.Position = 8
Dim snb(ust - 1) As Char
str.ReadBlock(snb, 0, ust)
Dim bst = New String(snb)
If usersm = 1 Then
str.BaseStream.Position = 16
Else
str.BaseStream.Position = 15
End If
cLVN(ListView1, bst, str.BaseStream.ReadByte)
str.BaseStream.Position = 8 + snb.Length
str.BaseStream.Position += str.BaseStream.ReadByte + 1
Else
Dim usn As Integer = str.BaseStream.ReadByte
str.BaseStream.Position += 2
Dim chrpos As Integer = str.BaseStream.Position
Dim xnl(usn - 1) As Char
str.Read(xnl, 0, usn - 1)
Dim skpbyte As Integer = str.BaseStream.ReadByte
str.BaseStream.Position += 3
Dim udata As Integer = str.BaseStream.ReadByte
End If
users -= 1
End While
End Using
End Using
ListView1.EndUpdate()
End Sub
When you change the position of the underlying stream, the StreamReader doesn't know you've done that. If it's previously read "too much" data (deliberately, for the sake of efficiency - it tries to avoid doing lots of little reads on the underlying stream) then it will have buffered data that it'll use instead of talking directly to the repositioned stream. You need to call StreamReader.DiscardBufferedData after repositioning the stream to avoid that.