Home > Programmer's Guide > More About Programming

Data Streams

All data input/output including communication are available to the programmer through the use of Stream objects.

Once you have understood how a Stream object works and its methods and properties, you will be able to read and write records in a database, send data by infrared, connect you to a server or read files on a VFS volume (a MemoryStick card for example).

Streams are represented in HB++ by the Stream class and its subclasses StreamFile, StreamFileDB, StreamExg, StreamMemory, StreamNull, StreamSerial, StreamSocket, StreamBluetooth, StreamCipher and StreamComposite.

A stream consists of data (sequences of bytes) and a pointer referencing a position within this sequence as well as functionality giving access to these components. You can establish an analogy between the use of streams and a video tape recorder connected to a television. We will be using this comparison to present the use of streams in HB++.

Concept related to streamsExplanation and analogy
DataA stream is used to receive data and to access it in a convenient way, just like the video tape stores images.
Size of the data (Size property)Just as a video tape has limited recording time, the HB++ streams intended for the storage of data cannot contain more than a certain amount of data.
Pointer (Position property)At any moment, the stream pointer references a position within the data (between the first and the last byte), just like the replay head, is at a given position between the beginning and end of the tape. Trying to reach a position out of these limits is incorrect and impossible.
Rewind (SeekToBegin method)It is possible to move the stream pointer to the first byte of the data, just like one rewinds a video tape.
Fast forward (SeekToEnd method)It is possible to move the stream pointer to the last byte of the data, just like one fast forwards a video tape to the first blank section.
Write (Write method)When you write data in a stream, the following operations are carried out: 1) the data is written at the current position of the cursor, erasing any data previously present at this position 2) the pointer advances to the position immediately after the written data 3) the stream length is updated to take account of any new data. This is exactly the same as a video tape recorder: the recording head erases any images present at the current position of the tape, the tape moves and the total duration of the recording increases. This operation can be carried out only if the stream can be written to, just like a video tape can be protected from recording and erasing.
Read (Read function)When reading data from a stream, the following operations are carried out: 1) data is read, if possible, from the current position of the cursor 2) if successful, the cursor is then positioned after the data that has just been read, 3) if reading is unsuccessful because the cursor is at the end of the stream, an error message is generated. It is exactly what occurs with a video tape recorder: the tape moves until it reaches the end.

The following example writes the first ten squares into a StreamMemory (stream manipulating a memory space) then reads them back again:

Dim s As New StreamMemory
Dim i As Integer

Private Sub Form_Load()
  For i = 1 To 10
    s.Write i * i
    list1.AddItem "O " & i*i & "     Pos : " & s.Position & " Size : " & s.Size
  Next i
  list1.AddItem "[]     Pos : " & s.Position & " Size : " & s.Size
End Sub

Private Sub Button1_Click()
  list1.Clear
  s.SeekToBegin
  list1.AddItem "<<     Pos : " & s.Position & " Size : " & s.Size
  While s.Position <> s.Size
    s.Read i
    list1.AddItem "> " & i & "     Pos : " & s.Position & " Size : " & s.Size
  Wend
End Sub

Data exchange streams

Watching a film recorded on a video tape compared to watching live television are not alike, in the same way, differences exist between the streams dedicated to file access or storage (StreamMemory, StreamFile), and data exchange (StreamExg, StreamSerial, StreamSocket, StreamBluetooth):

To find out more about the streams dedicated to communications, refer to the section about the StreamExg, StreamSerial, StreamSocket and StreamBluetooth objects.

Null streams

Lastly, there is a special type of stream, StreamNull. All data written in StreamNull is lost: the size of this stream thus remains equal to 0. It is impossible to read data from StreamNull. In our analogy, StreamNull would correspond to a disconnected cable. What does this stream do? Imagine that one of your applications must hold a log of the modifications carried out by the user. Your program will thus write a great amount of data into the stream log. Whilst debugging, you may not want to generate these log files in which case, simply replace the StreamFile with StreamNull.

For example :

Dim logStream As Stream

Private Sub logs(ByRef message As String)
  logStream.Write Now & ">" & message & "\n", hbWriteNoNull
End Sub

Private Sub Button1_Click()
  logs "click on button1"
End Sub

Private Sub Form_Load()
#If DEBUG Then
  Set logStream = New StreamNull
#Else
  Dim Vol As New VFSVolume
  If Vol.FindFirstVolume Then
    Set logStream = New StreamFile
    StreamFile(logStream).Open vol.Reference, "/log.txt", hbModeCreateAlways+hbModeReadWrite
  Else
    Set logStream = New StreamNull
  End If
#End If
End Sub

Private Sub Form_Unload()
#If NDEBUG Then
  StreamFile(logStream).Close
#End If
End Sub

Further Information

Consult the section on the Stream class and its derivatives StreamFile, StreamFileDB, StreamExg, StreamMemory, StreamNull, StreamSerial, StreamSocket, StreamBluetooth, StreamCipher and StreamComposite, as well as the Read and Write methods.