Class
BinaryStream
Description
BinaryStream objects are used to read and write data to and from a binary file. The benefit of using BinaryStreams rather than text streams is that you can read from and write to any position in the file. Text files must be read sequentially from the start to the end.
Properties
Name |
Type |
Read-Only |
Shared |
---|---|---|---|
Methods
Name |
Parameters |
Returns |
Shared |
---|---|---|---|
s As String |
|||
mb As MemoryBlock |
|||
file As FolderItem, overwrite As Boolean = False |
BinaryStream |
✓ |
|
type As Integer |
|||
type As IOStreamHandleTypes |
|||
file As FolderItem, readwrite As Boolean = False |
BinaryStream |
✓ |
|
byteCount As Integer, encoding As TextEncoding = Nil |
|||
encoding As TextEncoding = Nil |
|||
Data As String |
|||
Value As Boolean |
|||
Value As Currency |
|||
Value As Double |
|||
Value As Int16 |
|||
Value As Int32 |
|||
Value As Int64 |
|||
Value As Int8 |
|||
Text As String |
|||
Value As Double |
|||
Value As UInt16 |
|||
Value As UInt32 |
|||
Value As UInt64 |
|||
Value As UInt8 |
Constants
The following class constants can be used to specify the value of the Type parameter of the Handle property.
Class Constant |
Description |
---|---|
HandleTypeFileNumber |
A file descriptor |
HandleTypeFilePointer |
A file pointer |
HandleTypeWin32Handle |
A Windows32 OS handle |
Property descriptions
BinaryStream.BytePosition
BytePosition As UInt64
Gets or sets the current file position in the BinaryStream. The first position is numbered zero.
This property is automatically incremented by all of the Read and Write methods.
To move the position to the end of the stream, set it to BinaryStream.
This code changes the position from the default position of zero.
readStream.BytePosition = 100
BinaryStream.Length
Length As UInt64
The length of the file in bytes. If you set the Length property to a value smaller than its current value, it will truncate the file.
Var i As UInt64
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.Length
BinaryStream.LittleEndian
LittleEndian As Boolean
If True, the byte order is assumed to be low byte, high byte.
By default, BinaryStream reads data in the BigEndian byte order.
The following code sets the LittleEndian flag to True.
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
readStream.LittleEndian = True
Method descriptions
BinaryStream.Close
Close
Closes the stream (and hence the file opened by the stream).
This code backs a BinaryStream with a MemoryBlock that is declared 0-sized:
Var mb As New MemoryBlock(0)
Var bs As New BinaryStream(mb)
bs.WriteLong(4)
bs.WriteDouble(3.14)
bs.Close
MessageBox(mb.Long(0).ToString)
BinaryStream.Constructor
Constructor(s As String)
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a BinaryStream from a String.
Important
This method is not currently supported for Android.
BinaryStream.Constructor
Constructor(mb As MemoryBlock)
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a BinaryStream from a MemoryBlock.
Important
This method is not currently supported for Android.
BinaryStream.Constructor
Constructor(Handle As Integer, Type As Integer)
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a BinaryStream from an OS handle.
Important
This method is not currently supported for Android.
Type is one of the HandleType class constants and Handle is the appropriate handle type specified by the Type parameter.
The BinaryStream class constants given below can be passed as the parameter.
Constant |
Description |
---|---|
HandleTypeWin32Handle |
A Windows32 OS handle. |
HandleTypeFilePointer |
A file pointer. |
HandleTypeFileNumber |
A file descriptor. |
For instance, you can use a Declare to open a file with whatever permissions that you wish, and then pass the Handle to a stream object's constructor. When you do this, the BinaryStream now retains the ownership rights to the file handle, so you should not close the file handle (via a declare for example), since it will close when the BinaryStream is destructed.
Var b As New BinaryStream(i, BinaryStream.HandleTypeWin32Handle)
BinaryStream.Create
Create(file As FolderItem, overwrite As Boolean = False) As BinaryStream
Creates a file and opens a binary stream for reading and exclusive writing to the passed FolderItem.
This method is shared.
The overwrite parameter controls whether the operation can overwrite an existing file. The default is False.
Invoke Create using the syntax for shared methods, i.e. use BinaryStream.Create(...)
If the stream can not be opened as requested, an IOException will be raised. For instance, this will happen if the file is already opened for writing, or if the app (its user) has no permission to modify this file or to create a file in the affected directory.
This code reads each pair of bytes from a file and writes them in reverse order to a new file. The user chooses the source file using the Open-file dialog box and saves the new file using the Save as dialog box.
Var inputItem As FolderItem = FolderItem.ShowOpenFileDialog("")
If inputItem <> Nil Then
Var inputStream As BinaryStream = BinaryStream.Open(f, False)
Var outputItem As FolderItem = FolderItem.ShowSaveFileDialog("","")
If outputItem <> Nil Then
Try
Var outputStream As BinaryStream = BinaryStream.Create(f, True)
outputStream.LittleEndian = Not inputStream.LittleEndian
Do Until inputStream.EndOfFile
If inputStream.Length - inputStream.BytePosition >= 2 Then
outputStream.WriteUInt16(inputStream.ReadUInt16)
Else
outputStream.WriteUInt8(inputStream.ReadByte)
End If
Loop
Catch exc As IOException
MessageBox("Oops - failed to create the output file.")
End Try
End If
End If
BinaryStream.EndOfFile
EndOfFile As Boolean
Returns True when there's no more data left to read.
This code reads the rows and columns of data from a tab-delimited text file into a ListBox:
Var f As FolderItem
Var textInput As TextInputStream
Var rowFromFile As String
f = FolderItem.ShowOpenFileDialog("text/plain") ' defined as a FileType
If f <> Nil Then
textInput = TextInputStream.Open(f)
textInput.Encoding = Encodings.UTF8
Do
rowFromFile = textInput.ReadLine
Var values() As String = rowFromFile.ToArray(String.Chr(9))
ListBox1.ColumnCount = values.Count
ListBox1.AddRow("")
Var col As Integer
For Each value As String In values
ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, col) = value
col = col + 1
Next
Loop Until textInput.EndOfFile
textInput.Close
End If
This example reads each pair of bytes from a file and writes them in reverse order to a new file. The user chooses the source file using the Open-file dialog box and saves the new file using the Save as dialog box. The EOF property is used to terminate the Do...Loop.
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text")
If readFile <> Nil Then
Var ReadStream As BinaryStream = BinaryStream.Open(readFile, False)
ReadStream.LittleEndian = True
Var writeFile As FolderItem = FolderItem.ShowSaveFileDialog("", "")
If writeFile <> Nil Then
Var writeStream As BinaryStream = BinaryStream.Create(writeFile, True)
writeStream.LittleEndian = True
Do Until ReadStream.EndOfFile
writeStream.WriteInt8(ReadStream.ReadInt8)
Loop
writeStream = Nil
End If
readStream = Nil
End If
BinaryStream.Flush
Flush
Immediately sends the contents of internal write buffers to disk or to the output stream.
This function can be useful in point-to-point communication over sockets and similar connections: To optimize for transmission performance, some types of output streams try to collect small pieces of written data into one larger piece for sending instead of sending each piece out individually. By calling Flush, the data collection is stopped and the data is sent without further delay, reducing latency.
When using this on a stream that ends up as a file on disk, it is useful, too: Any short parts of previously written data are written to disk right away, ensuring the data is actually on disk if the application terminates abruptly, e.g. due to a crash.
Avoid calling this method too often. For example, do not call it between successive Write calls because you'll slow down performance without getting much benefit.
A typical use case would look like this:
mySocket.Write("you typed: ")
mySocket.Write(key)
mySocket.Write(".")
mySocket.Flush
BinaryStream.Handle
Handle(type As Integer) As Integer
Returns a handle of the Type passed.
Important
This method is not supported for Android.
The BinaryStream class constants given below can be passed as the parameter.
Name |
Description |
---|---|
HandleTypeWin32Handle |
A Windows32 OS Handle. |
HandleTypeFilePointer |
A file pointer. |
HandleTypeDescriptor |
A file descriptor. |
The following code gets a Win32 handle.
Var i As Integer
i = ReadStream.Handle(BinaryStream.HandleTypeWin32Handle)
Handle(type As IOStreamHandleTypes) As Ptr
Returns a handle of the Type passed.
Important
This method is not supported for Android.
BinaryStream.Open
Open(file As FolderItem, readwrite As Boolean = False) As BinaryStream
Opens the passed FolderItem as a binary stream. The readwrite parameter controls whether the file is open for read/write operations or read-only. When True, you can read and write to the file. When False you can only read from the file. The default is False. If an error occurs, an IOException is raised.
This method is shared.
Call Open using the syntax for a shared method.
This code reads a text file called "Whole File" and displays it in a TextArea. There is no attempt to parse the contents of the file.
Var f As New FolderItem("Whole File")
If f <> Nil Then
Try
Var bs As BinaryStream = BinaryStream.Open(f, False) ' Open as read-only
' read the whole binaryStream
TextArea1.Text = bs.Read(bs.Length)
Catch e As IOException
' something went wrong when opening the file. This is where you would handle the error
' if appropriate
End Try
End If
This code reads each pair of bytes from a file and writes them in reverse order to a new file. The user chooses the source file using the Open-file dialog box and saves the new file using the Save as dialog box.
Var inputItem As FolderItem = FolderItem.ShowOpenFileDialog("")
If inputItem <> Nil Then
Var inputStream As BinaryStream = BinaryStream.Open(f, False)
Var outputItem As FolderItem = FolderItem.ShowSaveFileDialog("","")
If outputItem <> Nil Then
Try
Var outputStream As BinaryStream = BinaryStream.Create(f, True)
outputStream.LittleEndian = Not inputStream.LittleEndian
Do Until inputStream.EndOfFile
If inputStream.Length - inputStream.BytePosition >= 2 Then
outputStream.WriteUInt16(inputStream.ReadUInt16)
Else
outputStream.WriteUInt8(inputStream.ReadByte)
End If
Loop
Catch exc As IOException
MessageBox("Oops - failed to create the output file.")
End Try
End If
End If
BinaryStream.Read
Read(byteCount As Integer, encoding As TextEncoding = Nil) As String
Reads byteCount bytes from the input stream and returns a String.
If provided, the optional parameter encoding specifies the text encoding to be defined for the String to be read.
If byteCount is higher than the amount of bytes currently available in the stream, all available bytes will be returned. Therefore, make sure to always consider the case that you get less than you requested. To see if you received all requested bytes, check the returned string's String property (avoid using Length as it may give a different number if the encoding is not nil).
If not enough memory is available, you get back an empty string.
This example reads the first 1000 bytes from a BinaryStream.
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var ReadStream As BinaryStream = BinaryStream.Open(readFile, False)
ReadStream.LittleEndian = True
TextArea1.Text = ReadStream.Read(1000, Encodings.UTF8)
End If
BinaryStream.ReadBoolean
ReadBoolean As Boolean
Reads a Boolean value from the stream and returns it as a Boolean.
If you read over the end of the stream you get false returned from this method. No error and no exception. If you need to check for this, you can check the EndOfFile, BytePosition, and Length properties.
The following code reads the next value from the BinaryStream as a Boolean.
Var b As Boolean
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
.
.
b = readStream.ReadBoolean
BinaryStream.ReadCurrency
ReadCurrency As Currency
Reads a Currency value from the stream and returns it as a Currency.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you want to check for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var d As Currency
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
.
d = readStream.ReadCurrency
BinaryStream.ReadDouble
ReadDouble As Double
Reads a double word from the stream and returns it as a Double.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var d As Double
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
d = readStream.ReadDouble
BinaryStream.ReadError
ReadError As Boolean
If True then an error occurred during reading.
BinaryStream.ReadInt16
ReadInt16 As Int16
Reads a two-byte value from the stream and returns it as an Int16.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you need to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As Int16
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadInt16
BinaryStream.ReadInt32
ReadInt32 As Int32
Reads a four-byte value from the stream and returns it as an Int32.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you need to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As Int32
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadInt32
BinaryStream.ReadInt64
ReadInt64 As Int64
Reads an eight-byte value from the stream and returns it as an Int64.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As Int64
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadInt64
End If
BinaryStream.ReadInt8
ReadInt8 As Int8
Reads a one-byte value from the stream and returns it as an Int8.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As UInt8
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadInt8
End If
BinaryStream.ReadPString
ReadPString(encoding As TextEncoding = Nil) As String
Reads a Pascal string from the stream and returns it as a String.
The optional parameter encoding enables you to specify the encoding to be defined on the returned string. Use the Encodings module to specify the text encoding. If you omit this parameter (or pass Nil), then the encoding of the returned string will be Nil.
If you read over the end of the stream you get an empty string returned from this method. No error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var s As String
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
s = readStream.ReadPString
End If
Important
This method is not currently supported for Android. Calling it will raise an AndroidException as PString is not a supported type on Android.
BinaryStream.ReadSingle
ReadSingle As Double
Reads a word from the stream and returns it as a Double.
If you read over the end of the stream you get zero returned from this method. No error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var num As Single
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
num = readStream.Single
End If
BinaryStream.ReadUInt16
ReadUInt16 As UInt16
Reads a two-byte value from the stream and returns it as a UInt16.
If you read over the end of the stream you get zero returned from this method. There is no error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As UInt16
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadUInt16
End If
BinaryStream.ReadUInt32
ReadUInt32 As UInt32
Reads a four-byte value from the stream and returns it as a UInt32.
If you read over the end of the stream you get zero returned from this method. There is no error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As UInt32
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadUInt32
End If
BinaryStream.ReadUInt64
ReadUInt64 As UInt64
Reads an eight-byte value from the stream and returns it as a UInt64.
If you read over the end of the stream you get zero returned from this method. There is no error and no exception. If you want to test for this error, you can check the EndOfFile, BytePosition, and Length properties.
Var i As UInt64
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadUInt64
End If
BinaryStream.ReadUInt8
ReadUInt8 As UInt8
Reads a one-byte value from the stream and returns it as a UInt8.
Var i As UInt8
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text/plain")
If readFile <> Nil Then
Var readStream As BinaryStream = BinaryStream.Open(readFile, False)
i = readStream.ReadUInt8
End If
BinaryStream.Write
Write(Data As String)
Writes the passed data to the output stream.
Note that in order to make sure that the data actually ends up on disk or gets sent to the socket it is connected to, the stream must either get closed or the Flush method be called. Otherwise, the data, if small, may end up temporarily in a write buffer before either a certain time has passed or more data is written. This buffering increases performance when writing lots of small pieces of data, but may be causing unwanted delays when another process, e.g. the other end of a socket connection, is waiting for the data. Consider calling the Flush method to reduce latencies that this buffering may cause in such cases.
If Write fails, an IOException will be raised.
This example displays the Save As dialog box and writes the contents of the TextArea1 to a text file.
Var f As FolderItem
Var stream As BinaryStream
f = FolderItem.ShowSaveFileDialog(FileTypes1.Text, "Untitled.txt")
If f<> Nil Then
stream = BinaryStream.Create(f, True)
stream.Write(TextArea1.Text)
stream.Close
End If
BinaryStream.WriteBoolean
WriteBoolean(Value As Boolean)
Writes the passed boolean to the stream.
Var b As Boolean = False
Var writeStream As BinaryStream
writeStream.WriteBoolean(b)
BinaryStream.WriteCurrency
WriteCurrency(Value As Currency)
Writes the passed Currency to the stream.
Var c As Currency = 540.34
Var writeStream As BinaryStream
writeStream.WriteCurrency(c)
BinaryStream.WriteDouble
WriteDouble(Value As Double)
Writes the value passed as a double word to the stream.
Var d As Double = 3.1416
Var writeStream As BinaryStream
writeStream.WriteDouble(d)
BinaryStream.WriteInt16
WriteInt16(Value As Int16)
Writes the passed Int16 to the stream.
Var i As Int16 = 5
Var writeStream As BinaryStream
writeStream.WriteInt16(i)
BinaryStream.WriteInt32
WriteInt32(Value As Int32)
Writes the passed Int32 to the steam.
Var i As Int32 = 5
Var writeStream As BinaryStream
writeStream.WriteInt32(i)
BinaryStream.WriteInt64
WriteInt64(Value As Int64)
Writes the passed Int64 to the stream.
Var i As Int64 = 5434555
Var writeStream As BinaryStream
writeStream.WriteInt64(i)
BinaryStream.WriteInt8
WriteInt8(Value As Int8)
Writes the passed Int8 to the stream.
Var i As Int8 = 8
Var writeStream As BinaryStream
writeStream.WriteInt8(i)
BinaryStream.WritePString
WritePString(Text As String)
Writes the text passed as a Pascal string to the stream.
Var s As String = "theString"
Var writeStream As BinaryStream
writeStream.WritePString(s)
BinaryStream.WriteSingle
WriteSingle(Value As Double)
Writes the value passed as a single word to the stream.
Var d As Single = 5.2437
Var writeStream As BinaryStream
writeStream.WriteSingle(d)
BinaryStream.WriteUInt16
WriteUInt16(Value As UInt16)
Writes the passed UInt16 to the stream.
Var i As UInt16 = 4
Var writeStream As BinaryStream
writeStream.WriteUInt16(i)
BinaryStream.WriteUInt32
WriteUInt32(Value As UInt32)
Writes the passed Uint32 to the steam.
Var i As UInt32 = 427
Var writeStream As BinaryStream
writeStream.WriteUInt32(i)
BinaryStream.WriteUInt64
WriteUInt64(Value As UInt64)
Writes the passed UInt64 to the stream.
Var i As UInt64 = 427
Var writeStream As BinaryStream
writeStream.WriteUInt64(i)
BinaryStream.WriteUInt8
WriteUInt8(Value As UInt8)
Writes the passed UInt8 to the stream.
Var i As UInt8 = 4
Var writeStream As BinaryStream
writeStream.WriteUInt8(i)
Notes
When the BinaryStream goes out of scope, it is flushed and closed.
Endian information
What is the LittleEndian property? The Windows and Linux operating systems store binary values in the reverse order from the macOS machines. If you were using the ReadInt16 or ReadIn32 methods to read data from a file that was in Little Endian format, you would get incorrect data. Data is read in Big Endian format by default. Most Mac files are in Big Endian format. If you are reading a file that is in Little Endian format, you will need to set the LittleEndian property to True before you begin reading the file. This applies to writing data with WriteInt16 and WriteInt32.
You can use the constants TargetLittleEndian and TargetBigEndian to determine which byte order is being used for a particular compile.
For example, in big endian (like the macOS), the value 258 would be stored as:
01 02
while in Little Endian, it would be stored as:
02 01
If the LittleEndian property is set incorrectly, then you would read the value as 513.
You can use the LittleEndian property to write your code to be OS-independent. Set the LittleEndian property to True if the file format is intrinsically little endian (i.e. GIF files), otherwise leave it as False.
Sample code
This example reads each pair of bytes from a file and writes them in reverse order to a new file. The user chooses the source file using the Open-file dialog box and saves the new file using the Save as dialog box.
Var readFile As FolderItem = FolderItem.ShowOpenFileDialog("text")
If readFile <> Nil And readFile.Exists Then
Var ReadStream As BinaryStream = BinaryStream.Open(readFile, False)
ReadStream.LittleEndian = True
Var WriteFile As FolderItem = FolderItem.ShowSaveFileDialog("", "")
If writeFile <> Nil Then
Var writeStream As BinaryStream = BinaryStream.Create(writeFile, True)
writeStream.LittleEndian = False
Do Until ReadStream.EndOfFile
writeStream.WriteInt32(ReadStream.ReadInt32)
Loop
writeStream.Close
End If
readStream.Close
End If
This code displays the Save As dialog box and writes the contents of the TextArea to a text file.
Var f As FolderItem
Var stream As BinaryStream
f = FolderItem.ShowSaveFileDialog(FileTypes1.Text, "Untitled.txt")
If f <> Nil Then
stream = BinaryStream.Create(f, True) ' Overwrite if exists
stream.Write(TextArea1.Text)
stream.Close
End If
Compatibility
All project types on all supported operating systems.
See also
Object parent class; FolderItem, IOException, MemoryBlock, TextInputStream, TextOutputStream classes; TargetBigEndian, TargetLittleEndian constants.