I need a way to read from a FileStream every single char. Char by Char.
Every time I read a char, I need to increment the FileStream.Position.
I am trying the code snippet, but it returns more than one char:
Dim bytes(1) As Byte
Dim nBytes As Integer = oFile.Read(bytes, 0, bytes.Length)
Dim nChars As Integer = decoder8.GetCharCount(bytes, 0, nBytes)
Dim chars(nChars - 1) As Char
nChars = decoder8.GetChars(bytes, 0, nBytes, chars, 0)
Return New String(chars, 0, nChars)
You could use a StreamReader and it's Read method instead, couldn't you?
Using rd = New StreamReader("path", Encoding.UTF8)
While rd.Peek() >= 0
Dim c As Char = Chr(rd.Read())
Console.WriteLine("Next character: " & c)
End While
End Using
StreamReader.Read
Reads the next character from the input stream and advances the
character position by one character.
Assuming that oFile is of type FileStream then
Dim nBytes As Integer = oFile.ReadByte()
should work.
Related
I've pulled a wave file from an online service I use and am now trying to save the returned stream. This is my code so far:
Using wavout = request.GetResponse.GetResponseStream
'error begins on next line
wavout.Seek(0, SeekOrigin.Begin)
Dim fs As FileStream = File.Create("output.wav")
Dim buf(65536) As Byte
Dim len As Integer = 0
While ((len = wavout.Read(buf, 0, 65536)) > 0)
fs.Write(buf, 0, len)
fs.Close()
End While
End Using
When I run the code it comes up with an exception saying 'this stream does not support seek operations'.
Can anyone see where I'm going wrong?
Some streams doesn’t support seeking. You can know it by a test such as “CanSeek”.
I’ve changed some lines in your code giving that as an answer to help you understanding the mechanism.
Dim request As Net.HttpWebRequest = CType(Net.WebRequest.Create("yoururlhere.com"), Net.HttpWebRequest)
Using wavout As IO.Stream = request.GetResponse().GetResponseStream()
'usnig this test you can avoid exceptions on seeking
If wavout.CanSeek Then
wavout.Seek(0, System.IO.SeekOrigin.Begin)
End If
Using fs As IO.FileStream = IO.File.Create("output.wav")
Dim buf(1024 * 8) As Byte
Dim len As Integer
Do
len = wavout.Read(buf, 0, buf.Length)
If len = 0 Then Exit Do
fs.Write(buf, 0, len)
Loop
End Using
End Using
I've got the need to escape any possible ascii escapes in a file. I've written this, and thought it was working well but just noticed that for some reason, there is a bunch of extra bytes at the end of the file now. There is probably a better way to do this, so here I am :) What's the best way to find bytes, and add a byte next to it?
Dim imageData() As Byte = File.ReadAllBytes(f_imagePath)
'Escape any ascii escapes
For i As Int32 = 0 To imageData.Length
If imageData(i) = &H1B Then
ReDim Preserve imageData(imageData.Length + 1)
'shift entire array
Dim arrCopy(imageData.Length + 1) As Byte
Array.Copy(imageData, 0, arrCopy, 0, i)
arrCopy(i) = &H1B
Array.Copy(imageData, i, arrCopy, i + 1, imageData.Length - i)
imageData = arrCopy
i = i + 1
End If
Next
Using a list...
Dim imageData() As Byte = File.ReadAllBytes(f_imagePath)
Dim newIMGData As New List(Of Byte)
'Escape any ascii escapes
For i As Int32 = 0 To imageData.Length
If imageData(i) = &H1B Then
'not sure about this,
newIMGData.Add(imageData(i)) 'add the &H1B
newIMGData.Add(&H0) 'add the other character
Else
newIMGData.Add(imageData(i))
End If
Next
imageData = newIMGData.ToArray
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
I have been trying my hand at handling packets and bytes for the first time, and I have not been able to obtain the packet length correctly so far after many different techniques.
Code:
Public Shared Sub Client(packet As Packet)
Console.WriteLine( _
"Client -> " & _
packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") & _
" length:" & Convert.ToString(packet.Length))
'Define Byte Array
Dim clientPacket As Byte() = packet.Buffer
' Open a Binary Reader
Dim memStream As MemoryStream = New MemoryStream(clientPacket)
Dim bReader As BinaryReader = New BinaryReader(memStream)
' Remove the Ethernet Header
Dim ethBytes As Byte() = bReader.ReadBytes(14)
' Remove the IPv4 Header
Dim IPv4Bytes As Byte() = bReader.ReadBytes(20)
' Remove the TCP Header
Dim TCPBytes As Byte() = bReader.ReadBytes(20)
' Get the packet length
If clientPacket.Length > 54 Then
Dim len As UInt32 = bReader.ReadUInt32
Console.WriteLine(len)
End If
End Sub
So far, all of my attempts at having the console write the data length have resulted in failure. I validated the endianness and actually wrote out the bytes to verify that I was handling the correct data.
Example bytes:
00 00 00 24 -> UINT32 is 36 bytes, but I am getting an array of Integers like 3808493568
How can I fix this?
I agree with Hans, endianness is your problem. Also, I'd recommend you use the BitConverter class on the clientPacket array, easier than using streams.
Dim len As UInt32
Dim arr() As Byte
arr = {0, 0, 0, 24}
len = BitConverter.ToUInt32(arr, 0)
Console.Write(len.ToString) 'returns 402653184
arr = {24, 0, 0, 0}
len = BitConverter.ToUInt32(arr, 0)
Console.Write(len.ToString) 'returns 24
For your code, I think this might work (untested):
If clientPacket.Length > 54 Then
Dim lenBytes As Byte() = bReader.ReadBytes(4)
Array.Reverse(lenBytes, 0, 4)
Dim len As UInt32 = BitConverter.ToUInt32(lenBytes, 0)
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.