How to: Work with Data Streams
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
An entity in the Telerik Data Access domain model can expose binary large objects, also known as BLOBs. This binary data might represent video or audio streams, images, document files, or other types of binary media. Binary large objects (BLOBs) need different treatment, because they can contain gigabytes of data and this can affect the application performance. That's why Telerik Data Access provides special support (API) for working with BLOBs.
In this topic, you will see:
- How to work with the BinaryStream type
- How to read binary data from the database
- How to write binary data to the database
Working with the BinaryStream Type
The BinaryStream type is a special type that exposes a stream around a database binary field. By default when you map a table with a binary column, the corresponding property in the Visual Designer is of type byte[].
The BinaryStream type can be used against varbinary(MAX) columns in MSSQL and the corresponding ones in other backends. For example, if you try to use it with a column of type Image, you will get an exception. The support backends/sql types are as follows:
- MSSQL - varbinary(MAX)
- PostgreSQL - bytea
- MySql - longblob
- Oracle - blob
The new BinaryStream type is not mapped automatically when the column is of binary type. You have to manually change the type of the generated property in the Visual Designer (or in the fluent model). Then you can work with the stream property as any other streams.
Reading Binary Data From the Database
The following example shows how to use the Read method of the BinaryStream class to read an image from the database and save it on the local hard drive. The Read method reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
using ( EntitiesModel dbContext = new EntitiesModel() )
{
FileStream stream = new FileStream( "CategoryImage.jpg",
FileMode.Create, FileAccess.Write );
BinaryWriter writer = new BinaryWriter( stream );
Category firstCategory = dbContext.Categories.Last();
int numBytesToRead = ( int )firstCategory.Picture.Length;
byte[] bytes = new byte[65536];
int bytesRead = 1;
while ( numBytesToRead > 0 && bytesRead > 0 )
{
bytesRead = firstCategory.Picture.Read( bytes, 0,
Math.Min( numBytesToRead, bytes.Length ) );
writer.Write( bytes );
numBytesToRead -= bytesRead;
}
writer.Flush();
writer.Dispose();
}
Using dbContext As New EntitiesModel()
Dim stream As New FileStream("CategoryImage.jpg", FileMode.Create,
FileAccess.Write)
Dim writer As New BinaryWriter(stream)
Dim firstCategory As Category = dbContext.Categories.Last()
Dim numBytesToRead As Integer = CInt(Fix(firstCategory.Picture.Length))
Dim bytes(65535) As Byte
Dim bytesRead As Integer = 1
Do While numBytesToRead > 0 AndAlso bytesRead > 0
bytesRead = firstCategory.Picture.Read(bytes, 0,
Math.Min(numBytesToRead, bytes.Length))
writer.Write(bytes)
numBytesToRead -= bytesRead
Loop
writer.Flush()
writer.Dispose()
End Using
Writing Binary Data to the Database
The following example shows how to use the Write method of the BinaryStream class to insert an image in the database. The Write method writes a sequence of bytes to the current stream and advances the current position within the stream by the number of bytes written. Another important thing to note is the Append property of the BinaryStream class. It indicates whether the stream will replace the binary field with update statements or will just append the new data.
Note that the BinaryStream property is automatically initialized by the runtime. You don't need to explicitly create a new instance.
using ( EntitiesModel dbContext = new EntitiesModel() )
{
Category category = new Category();
category.CategoryName = "Demo Category";
category.Description = "Demo Description";
dbContext.Add( category );
dbContext.SaveChanges();
using ( FileStream stream = File.OpenRead( "Input.jpg" ) )
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ( ( bytesRead = stream.Read( buffer, 0, buffer.Length ) ) > 0 )
{
category.Picture.Write( buffer, 0, bytesRead );
}
}
category.Picture.Flush();
dbContext.SaveChanges();
}
Using dbContext As New EntitiesModel()
Dim _category As New Category()
_category.CategoryName = "Demo Category"
_category.Description = "Demo Description"
dbContext.Add(_category)
dbContext.SaveChanges()
Using stream As FileStream = File.OpenRead("Input.jpg")
Dim buffer(1023) As Byte
Dim bytesRead As Integer = 0
bytesRead = stream.Read(buffer, 0, buffer.Length)
Do While bytesRead > 0
_category.Picture.Write(buffer, 0, bytesRead)
bytesRead = stream.Read(buffer, 0, buffer.Length)
Loop
End Using
_category.Picture.Flush()
dbContext.SaveChanges()
End Using