Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
A simple class to implement multiple files "in a file" Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Files Operation
Delphi 4.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: david bolton

How do I store multiple files within one compound file?


Microsoft have been doing this for years with the OLE compound files (used in Excel 
etc) and there is Delphi code to work with them available at but I wanted to 
reinvent this particular wheel- in particular I wanted compression and encryption 
(albeit fairly lightweight). I also know about Abbrevia 3 from TurboPower which is 
a compression toolkit that includes something similar. 

The result is TcompoundVolume. It uses Bzip2, a freeware Delphi compression library 
by Edison Mera Menéndez from Ecuador. I highly recommend Bzip2 which can be found 
on www.torry.net and in the zip file accompanying this article. 
It is small and fast. As the Class code for TcompoundVolume is about 1,000 lines 
long, I’ve not listed it but instead given examples of its use. 

The intention of TcompoundVolume was to provide a convenient “sub-database” way of 
storing data and dynamically updating it or retrieving it. I made my life slightly 
more interesting by having one file rather than say an index and a data file. A 
simple directory structure is kept at the end of the file and rewritten after 

Each instance of the class  is associated with a file, and the constructor creates 
a blank file if the file doesn’t exits. I tend to uses two instances, one for large 
static data, the other for dynamic data.   

Creating an instance of the class 
2   Comp := TCompoundVolume.Create('test.dat');

This opens or creates the volume file test.dat 

To add a file – either 

AddFile(Filename, Stream) or AddFileFromDisk(FileName)

3   Comp.AddFileFromDisk('SAMPLE\1.txt');
4   Comp.AddFile('names', NameStream);

Stream is any Tstream descendant so A String Stream or Memory Stream can be used. 

Both Methods can have an extra parameter GroupNum which defaults to 0. GroupNum is 
a crude way of implementing a ‘directory’ structure. You can add files to a group 
(0-255).  Two functions CVFindFirst and CVFindNext retrieve filenames from the 
Volume just like the FindFirst and FindNext functions for traversing folders. 

5   var
6     Er: integer;
7     sg: string;
9   begin
10    sg := '';
12    Er := CVFindFirst(Group, sg, details);
14    while er = 0 do
15    begin
16      ShowMessage(Sg);
17      er := CvFindNext(Sg);
18    end;

To retrieve any stored file, you need a TmemoryStream component. The object is 
created for you, but don’t forget to free it. 

19  ms := comp.files['test'];
20  if assigned(ms) then
21  begin
22    ShowMessage('File test is ' + inttostr(ms.size) + ' bytes long');
24  end;

Comp. FilesString[ filename ] doers the same but returns a tstringlist, 

That’s about it. There are a couple of other features worth mentioning. 
PackVolume() compresses the Volume by copying valid data into another file. There 
is also the Prefs method which lets you store string variables in the Volume. Eg 
Comp.Prefs[‘login’] := ‘xxx’; This creates a file called prefs and stores the 
values as Name, Value pairs. 

Encryption (lightweight xor) is on by default but can be disabled if the Encryption 
method is set false. This uses “security by obscurity” which means its not really 
secure! Add your own encryption if that is an issue. 

Architecturally, the directory (of offsets to the start of each file) is kept at 
the end of the file and updated when the object is freed. So if you add a file but 
the object isn’t terminated correctly, perhaps due to an exception, it can corrupt 
the volume as the updated directory isn’t written back. 

Each offset is an integer file pointer to the start of the file block which holds 
details about the file. These are loaded into a sorted string/object list in memory 
when the object is created. 

This class should be considered a bit rough and ready at the beta level.  I’ve 
tested it with Delphi 4 & 5, but not 6 though it should work with that. It might 
even work with D3! 

I’m sure it could be rewritten to be better. If anyone improves it, all I ask is 
that you email a copy to me. You 
are free to use it as you wish, without any licensing conditions whatsoever. It is 
freeware and is given to the Delphi community.  Use it freely but any risk is your 
risk alone. I give no warranties as to its fitness of purpose. 

Component Download:

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC