Looking at the put instances of the various ByteString types we find that the length of the bytestring is always prefixed in the binary file before writing it. For example here - https://hackage.haskell.org/package/binary-0.8.8.0/docs/src/Data.Binary.Class.html#put
Taking an example
instance Binary B.ByteString where
put bs = put (B.length bs) -- Why this??
<> putByteString bs
get = get >>= getByteString
Is there any particular reason for doing this? And is the only way to write Bytestring without prefixing the length - creating our own newtype wrapper and having an instance for Binary?
The idea of
getandputis that you can combine several objects. For example you can write:then you want to define a function that can read the data back, and evidently you want the two functions to act together as an identity function: that if the writer writes a certain
ByteStringand a certainChar, then you want the read function to read the sameByteStringand character.The reader function should look similar to:
but the problem is, when does a
ByteStringends? The'A'character could also be part of theByteString. You thus need to somehow indicate where theByteStringends. This can be done by saving the length, or some marker at the end. In case of a marker, you will need to "escape" the bytestring, such that it can not contain the marker itself.But you thus need some mechanism to specify that when the
ByteStringends.No, in fact it is already in the
instancedefinition. If you want to write aByteStringwithout length, then you can useputByteString :: ByteString -> Put:but when reading the
ByteStringback, you will need to figure out how many bytes you have to read.