Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to copy multiple files into one (2) 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
20-Oct-02
Category
Files Operation
Language
Delphi 2.x
Views
85
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Jonas Bilinkevicius

What is the quickest way of merging loads of files together, and being able to pull 
them out when needed in the application all files have unique names, I need to 
merge the files as the application could create 10000+ and all them being in one 
dirctory, well lets say windows does not handle it very well specially the fact 
that they are all small file with the odd occasion of a 15mb file, so I need a 
better way off managing it not interested in compression I want something that is 
as quick or quicker than access an individual file.

Answer:

Solve 1:

If you do not need random access to the files in the larger file (in which case you 
need an index, a kind of directory) you can simply concatenate the source files, 
storing the file name and size for each file in front of the files data.
1   
2   procedure ConCatFiles(const targetname: string; const Sourcenames: TStrings);
3   var
4     i: Integer;
5     target, source: TFileStream;
6     fsize: Longint;
7   begin
8     target := TFileStream.Create(targetname, fmCreate);
9     try
10      for i := 0 to Sourcenames.Count - 1 do
11      begin
12        source := TFileStream.Create(Sourcenames[i], fmOpenread or fmShareDenyNone);
13        try
14          fsize := Length(Sourcenames[i]);
15          target.write(fsize, Sizeof(fsize));
16          target.write(Sourcenames[i][1], fsize);
17          fsize := source.size;
18          target.write(fsize, Sizeof(fsize));
19          target.Copyfrom(source, 0);
20        finally
21          source.free;
22        end;
23      end;
24    finally
25      target.Free;
26    end;
27  end;
28  
29  procedure UnmergeFiles(const sourcename: string);
30  var
31    i: Integer;
32    target, source: TFileStream;
33    fsize, sourcesize: Longint;
34    fname: string;
35  begin
36    source := TFileStream.Create(sourcename, fmOpenread or fmShareDenyNone);
37    try
38      sourcesize := source.size;
39      while source.position < sourcesize do
40      begin
41        source.read(fsize, Sizeof(fsize));
42        SetLength(fname, fsize);
43        source.read(fname[1], fsize);
44        target := TFileStream.Create(fname, fmCreate);
45        try
46          source.read(fsize, Sizeof(fsize));
47          target.Copyfrom(source, fsize);
48        finally
49          target.free;
50        end;
51      end;
52    finally
53      source.Free;
54    end;
55  end;


Untested! And of course you should think about how to handle pathes in this context.


Solve 2:

I've written a little example that doesn't consume too much memory. It concatenates 
and compresses files into one destination file (CompressFiles) and can restore then 
in a given location (DecompressFiles).

56  { ... }
57  implementation
58  
59  {$R *.dfm}
60  
61  uses
62    zLib;
63  
64  procedure CompressFiles(Files: TStrings; const Filename: string);
65  var
66    infile, outfile, tmpFile: TFileStream;
67    compr: TCompressionStream;
68    i, l: Integer;
69    s: string;
70  begin
71    if Files.Count > 0 then
72    begin
73      outFile := TFileStream.Create(Filename, fmCreate);
74      try
75        {the number of files}
76        l := Files.Count;
77        outfile.write(l, SizeOf(l));
78        for i := 0 to Files.Count - 1 do
79        begin
80          infile := TFileStream.Create(Files[i], fmOpenRead);
81          try
82            {the original filename}
83            s := ExtractFilename(Files[i]);
84            l := Length(s);
85            outfile.write(l, SizeOf(l));
86            outfile.write(s[1], l);
87            {the original filesize}
88            l := infile.Size;
89            outfile.write(l, SizeOf(l));
90            {compress and store the file temporary}
91            tmpFile := TFileStream.Create('tmp', fmCreate);
92            compr := TCompressionStream.Create(clMax, tmpfile);
93            try
94              compr.CopyFrom(infile, l);
95            finally
96              compr.Free;
97              tmpFile.Free;
98            end;
99            {append the compressed file to the destination file}
100           tmpFile := TFileStream.Create('tmp', fmOpenRead);
101           try
102             outfile.CopyFrom(tmpFile, 0);
103           finally
104             tmpFile.Free;
105           end;
106         finally
107           infile.Free;
108         end;
109       end;
110     finally
111       outfile.Free;
112     end;
113     DeleteFile('tmp');
114   end;
115 end;
116 
117 procedure DecompressFiles(const Filename, DestDirectory: string);
118 var
119   dest, s: string;
120   decompr: TDecompressionStream;
121   infile, outfile: TFilestream;
122   i, l, c: Integer;
123 begin
124   dest := IncludeTrailingPathDelimiter(DestDirectory);
125   infile := TFileStream.Create(Filename, fmOpenRead);
126   try
127     {number of files}
128     infile.read(c, SizeOf(c));
129     for i := 1 to c do
130     begin
131       {read filename}
132       infile.read(l, SizeOf(l));
133       SetLength(s, l);
134       infile.read(s[1], l);
135       {read filesize}
136       infile.read(l, SizeOf(l));
137       {decompress the files and store it}
138       s := dest + s; {include the path}
139       outfile := TFileStream.Create(s, fmCreate);
140       decompr := TDecompressionStream.Create(infile);
141       try
142         outfile.CopyFrom(decompr, l);
143       finally
144         outfile.Free;
145         decompr.Free;
146       end;
147     end;
148   finally
149     infile.Free;
150   end;
151 end;


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

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC