❔ Read bits from a byte[] array
Hi, I was looking for a way to read bits in a byte[] array and advance the position, and I came across the BitStream library (https://github.com/Sewer56/Sewer56.BitStream) because we can't do it natively in C#.
The problem is that I've noticed that I'm not getting the expected behavior in my code
At first, I need to read an int32 in my byte stream, so I did :
And in output I get :
Normally I'd get something shorter like this:
I don't want to write a code that will only retrieve the first two characters because I don't necessarily know the size
Do you know why the BitStream library reacts like this? When I use MemoryStream + BinaryReader it works perfectly except that I get stuck when I have to read bits in a stream...
Thanks a lot 🙏
50 Replies
So you do
Read<int>
, but expect it to read a byte and skip the next 3 bytes?Thanks for your answer
In the library, using
Read<int>()
means that I want to read 32 bits (4 bytes), and advance the position by 4 bytes.because we can't do it natively in C#Absolutely wrong. Just to be clear: you want to read
int32
from byte[]
?And is that not the exact behavior you're seeing?
Yes, I know that we can read an int32 natively EXCEPT that in the rest of my code I have to read bits and we can't do that natively
It's difficult to understand your goal honestly
Is this what you need?
Basically, I have a UDP client that must read packets sent to me by a UDP server
In the stream I receive, I have to read both integers and bits
In C#, we can only read bytes in a stream
there's also BitArray
but i guess he knows
Basically I have this:
Except that the values I get are much larger than if I use MemoryStream + StreamReader
larger?
ah ok the 671088640
Yep
Well, this works as expected.
Read<int>()
reads one 32-bit integer and advances position by 4 bytes. And values around 600M are reasonable for 32bit int
. If you want to read a single byte, then Read<byte>()
Okay, but why get a different value in the console? If I use MemoryStream + BinaryReader or something else, I'll get the same values, but smaller
ReadByte()
from *Stream
reads exactly one 8bit integer ('byte'), but returns it as a 32bit integer (int
)
https://learn.microsoft.com/dotnet/api/system.io.stream.readbyteI think it's a cast problem, yes, because in my code there are conditions that check whether the header variable corresponds to something and I never get to that condition, whereas if I use MemoryStream + BinaryReader it works
BinaryReader.Read returns a byte
eh, late
but are you trying to make a integer from an arbitrary number of bits?
So use
BitStream.Read<byte>()
to get the same behaviour as MemoryStream.ReadByte()
Yes, I get the same behavior, but from the moment I start reading 4 bytes I don't get the same values
yes, because reading 4 bytes is not the same as reading 1 byte
(wouldn't be better using uint instead of int? btw)
I need to read negative values in the header variable because basically the packet id can be -1, -3 etc
weird but ok i guess
To keep things simple, the server will write a int32 at the beginning of the packet, which I must read to retrieve the value
did you check if the bitStream endianness == binReader endianness?
ero
REPL Result: Success
Result: ValueTuple<string, string>
Compile: 987.689ms | Execution: 73.854ms | React with ❌ to remove this embed.
Read32
from BitStream
returns a uint
BitStream reads big endian data
https://github.com/Sewer56/Sewer56.BitStream/issues/2
i don't think it does
ero
REPL Result: Failure
Exception: CompilationErrorException
Compile: 502.803ms | Execution: 0.000ms | React with ❌ to remove this embed.
ero
REPL Result: Success
Result: ValueTuple<string, string>
Compile: 567.905ms | Execution: 68.540ms | React with ❌ to remove this embed.
guess it does
I get
0x00000035
when using MemoryStream + BinaryReader and 0x35000000
when using BitStreamwhich is pretty self explanatory
Yes, except that there's no lib capable of reading a byte stream in little endian :/
yeah i mean i laid out very clearly why that is
and i also provided some code that reads a byte buffer as little endian
Yes, it works, but I can't read several values in my byte stream
hm?
For example, if I then want to read 3 bits from my byte stream, the ReadInt32BigEndian method won't advance the stream by 4 bytes, do you understand?
i mean i would read an
int
and then do & 0b111
on the resultDo you have an example, please? Because I'm lost :x
you can take what the stream is returning, so at least a byte
then wrap it to consume the bits
i guess he's saying that
obviously it means writing your own bit stream
ero
REPL Result: Success
Result: ValueTuple<int, int>
Compile: 468.504ms | Execution: 41.094ms | React with ❌ to remove this embed.
i'm pretty sure there are way bigger underlying issues that we can't really help with without way more detail
more issues = more code = more fun
right?
It's no problem to swap it manually after reading
Yup
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.