Built-in db4o Blob type helps you to get rid of the problems of byte[] array, though it has its own drawbacks. Pros and Cons for the points, mentioned above:
+ main database file stays a lot smaller
+ backups are possible over individual files
+ the BLOBs are accessible without db4o
- multiple files need to be managed
+ asynchronous storage allows the main application thread to continue its work, while blobs are being stored
- it is more difficult to move objects between db4o database files
+ big objects won't be loaded into memory as part of the activation process
Let's look, how it works.
First, BLOB storage should be defined:
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02
namespace Db4objects.Db4odoc.Blobs 03
{ 04
public class Car 05
{ 06
string _model; 07
CarImage _img; 08
09
public Car(string model) 10
{ 11
_model = model; 12
_img=new CarImage(); 13
_img.FileName = _model+".jpg"; 14
} 15
16
public CarImage CarImage 17
{ 18
get 19
{ 20
return _img; 21
} 22
} 23
24
override public string ToString() 25
{ 26
return string.Format("{0}({1})", _model, _img.FileName); 27
} 28
} 29
}
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Blobs 03
Public Class Car 04
Dim _model As String 05
Dim _img As CarImage 06
07
Public Sub New(ByVal model As String) 08
_model = model 09
_img = New CarImage() 10
_img.FileName = _model + ".jpg" 11
End Sub 12
13
Public ReadOnly Property CarImage() As CarImage 14
Get 15
Return _img 16
End Get 17
End Property 18
19
Public Overrides Function ToString() As String 20
Return String.Format("{0}({1})", _model, _img.FileName) 21
End Function 22
End Class 23
End Namespace
[/filter]
CarImage is a wrapper to BLOB, representing the photo:
inFolder ( "blobs\in\") is used as a location of existing files, which are to be stored into db4o, and outFolder ( "blobs\out\") will be the place for images, retrieved from the database.
readFile method allows blob to be read from the specified location into db4o storage:
As reading is done in a dedicated thread, you can use Blob#getStatus() in a loop to create a progress window.
The same applies to the write operation, which copies BLOB, stored with db4o, to the specified filesystem location.
Let's store some cars together with their images in our database:
01private static void StoreCars() 02
{ 03
File.Delete(Db4oFileName); 04
IObjectContainer db = Db4oFactory.OpenFile(Db4oFileName); 05
try 06
{ 07
Car car1=new Car("Ferrari"); 08
db.Set(car1); 09
StoreImage(car1); 10
Car car2=new Car("BMW"); 11
db.Set(car2); 12
StoreImage(car2); 13
} 14
finally 15
{ 16
db.Close(); 17
} 18
}
01Private Shared Sub StoreCars() 02
File.Delete(Db4oFileName) 03
Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04
Try 05
Dim car1 As Car = New Car("Ferrari") 06
db.Set(car1) 07
StoreImage(car1) 08
Dim car2 As Car = New Car("BMW") 09
db.Set(car2) 10
StoreImage(car2) 11
Finally 12
db.Close() 13
End Try 14
End Sub
[/filter]
01private static void RetrieveCars() 02
{ 03
IObjectContainer db = Db4oFactory.OpenFile(Db4oFileName); 04
try 05
{ 06
IQuery query = db.Query(); 07
query.Constrain(typeof(Car)); 08
IObjectSet result = query.Execute(); 09
GetImages(result); 10
} 11
finally 12
{ 13
db.Close(); 14
} 15
}
01Private Shared Sub RetrieveCars() 02
Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03
Try 04
Dim query As IQuery = db.Query() 05
query.Constrain(GetType(Car)) 06
Dim result As IObjectSet = query.Execute() 07
GetImages(result) 08
Finally 09
db.Close() 10
End Try 11
End Sub
and get BLOB data using retrieved Car references:
01private static void GetImages(IObjectSet result) 02
{ 03
while(result.HasNext()) 04
{ 05
Car car = (Car)(result.Next()); 06
Console.WriteLine(car); 07
CarImage img = car.CarImage; 08
try 09
{ 10
img.WriteFile(); 11
} 12
catch (Exception ex) 13
{ 14
Console.WriteLine(ex.Message); 15
} 16
} 17
}
01Private Shared Sub GetImages(ByVal result As IObjectSet) 02
While result.HasNext() 03
Dim car As Car = CType((result.Next()), Car) 04
Console.WriteLine(car) 05
Dim img As CarImage = car.CarImage 06
Try 07
img.WriteFile() 08
Catch ex As Exception 09
Console.WriteLine(ex.Message) 10
End Try 11
End While 12
End Sub
Retrieved images are placed in CarImage.outFolder ("blobs\out").
So query interface operates on references - no BLOB data is loaded into memory until explicit call (Blob#writeTo). This also means, that activationDepth does not affect Blob objects and best querying performance is achieved without additional coding.