Monday, August 22, 2011

Big files

 In a big project you might end up with tons of files, maybe you group them by directory, but it can be quite handy to group them all into a single file, for that purpose we have the TBigFile class, which contains the following methods:


  TBigFile = class
    constructor Create;
    destructor Destroy; override;
    procedure AddStream(const aName: string; aStream: TStream);
    procedure AddFile(const aFileName: string);
    procedure BuildFrom(const aFileName: string);
  	procedure Clear;
    function GetFiles: TStrings; overload;
    function GetFiles(const aPath, aMask: string): TStrings; overload;
    function GetDirectories: TStrings;
    function Load(const aPath, aFileName: string): TStream; overload;
    function Load(const aFileName: string): TStream; overload;
    procedure Save(const aFileName: string);

    property Signature: AnsiString read FSignature write FSignature;
  end;
In the demos file, there is a project named BigFile.dpr which shows how to create and load a big file, let's make a summary:
Create the class

FBig := TBigFile.Create;
Add some files

FBig.AddStream('test.txt', stream);
Since the parameter is a stream we can add any kind of resource, aditionally there is a method for directly add physical files called AddFile(). 

You can also specify different folders just add the folder name prior to the file name like 'one/test.txt'

Save the big file

FBig.Save('TheOne.big');
Load the big file

FBig.BuildFrom('TheOne.big');
Loading files

stream := FBig.Load('test.txt')
In the BB API, there are many load functions that support streams, so one can do 
things like 
ent.LoadStream(FBig.Load('donut.asc'));
Getting files

strings := FBig.GetFiles;
Now strings will contain all files located inside the big file, there is an overloaded method to retrieve files per directory and mask
strings := FBig.GetFiles('first', '*.bmp');
These are the classes that support streams:
  • TEnt
  • TAnimations
  • TSimpleSprite
  • TLayer
  • TIni
  • TImageEx
  • TSurface
Of course those streams can be compresses/decompressed, an easy way is to use the helper class TStreamHelper which holds several methods to help you:
  TStreamHelper = class helper for TStream
public 
  function ToString: string
  procedure WriteString(const aString: string);
  function Bof: boolean;
    function Eof: boolean; 
  class function Compress(aStream: TStream): TStream; 
  class function Decompress(aStream: TStream): TStream; 
  class function StreamToString(aStream: TStream): string
  class function StringToStream(const aString: string): TStream; 
  class function MemoryToStream(aBuffer: pointer; aSize: int64): TStream; 
  class function StringToCompressed(const aString: string): TStream; 
  class function CompressToString(aStream: TStream): string
  class function ComponentToStream(aComponent: TComponent): TStream; 
  class function ComponentToString(aComponent: TComponent): string
  class procedure Save(const aFileName: string; aStream: TStream); 
end;

No comments:

Post a Comment