ARTICLE

Combine streams in one .NET Framework Stream object using VB.NET

Posted by info Articles | Visual Basic 2010 November 04, 2004
This article represents a simple Stream class whose data is based on the number of another .NET Framework streams.
Download Files:
 
Reader Level:

Abstract.

This article represents a simple Stream class whose data is based on the number of another .NET Framework streams.

There are some tasks when you may want to provide the data combined from different parts via Stream interface. The most obvious way is to create the MemoryStream class instance and copy all data parts (streams in our case) into this single object. This solution has only one good thing - the simplicity and you can use it for sure for combining of small footprint streams without bothering about the reverse of the medal. While working with the large size streams or having big number of streams such primitive copying of data chunks may lead to bad application performance and irrational using of virtual memory.

MultiStream Class Declaration.

In order to effectively combine number of streams into the single Stream class descendant you will need to organize access to streams data in appropriate order.

We will create new MultiStream inherited from .NET base abstract Stream class. Methods Read, Seek, Write and also Length property need to be overriden and implemented within MultiStream class. All remaining abstract Stream members have the obvious implementation and to be shortest we do not place them here. But you can find the full source code for this class at multistreamcs.zip.

The code below shows the implementation of the Read method of MultiStream class:

Public Overrides Function Read(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer) As Integer
Dim
len As Long = 0
Dim result As Integer = 0
Dim buf_pos As Integer = offset
Dim bytesRead As Integer
For
Each stream As Stream In streamList
If position < (len + stream.Length) Then
stream.Position = position - len
bytesRead = stream.Read(buffer, buf_pos, count)
result += bytesRead
buf_pos += bytesRead
position += bytesRead
If bytesRead < count Then
count -= bytesRead
Else
Exit
For
End
If
End
If
len += stream.Length
Next stream
Return result
End Function

This method walks through all streams being stored within the streamList member of MultiStream class and checks each of them for matching the MultiStream Position. If the current stream position plus total all of the previous streams sizes matches to the main Position then data from this stream will be transferred until requested buffer size extends up to the another stream items.

The Seek method implements locating of the TMultiStream Position pointer using the total size of collected stream items:

Public Overrides Function Seek(ByVal offset As Long, ByVal origin As SeekOrigin) As Long
Dim
len As Long = Length
Select Case origin
Case SeekOrigin.Begin
position = offset
Case SeekOrigin.Current
position += offset
Case SeekOrigin.End
position = len - offset
End Select
If
position > len Then
position = len
Else If position < 0 Then
position = 0
End If
Return
position
End Function

Please note that the contents of the MultiStream can not be modified by calling of Write method. So implementation of this method will be very simple:

Public Overrides ReadOnly Property CanWrite() As Boolean
Get
Return False
End
Get
End
Property

Indeed it is quite difficult to imagine such task when you might need to change the contents of the multistream object.

Using of MultiStream Class.

With just few lines of code the new MultiStream class is ready to use. Lets go ahead and test it:

Private stream As MultiStream = New MultiStream()
stream.AddStream(
New StringStream("test string "))
stream.AddStream(
New FileStream("testfile.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
Dim buf As Byte() = New Byte(1023){}
Dim cnt As Integer = stream.Read(buf, 0, 1024)
Debug.Assert(
New ASCIIEncoding().GetString(buf, 0, cnt).Equals("test string test file")).

This code is constantly being improved and your comments and suggestions are always welcome.

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# CORNER (WWW.C-SHARPCORNER.COM).

share this article :
post comment
 
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor