原文
3 v8 E. e5 {$ R6 y8 H$ r9 G6 Yhttp://pygments.org/demo/599/4 R6 i: V. e8 _ ]# e
; S; @, o) E0 y# B9 uCyroBF Extract
; s# R- a* g% N7 I' I# G+ m) g, ~" H; _# V9 y" w: J) @. O
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native : A: X4 i! y( j2 j( E/ |
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m.
1 V: Y) v) Q3 A/ {$ W2 n5 oLanguage: Delphi. Code size: 4.0 KB. 5 A ~5 O# B1 w
" e3 C8 X! h. A2 \. `( G7 z/ e0 i
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);5 M0 O4 e/ x/ Z' i+ J4 o% g" f
var
# Z! }4 L L& I# D6 W9 I1 I SaveFile: TFileStream;% M+ m4 M9 t9 V& @, _
SaveCurrentPosition: Int64;
/ N% v! i" I6 r+ @) kbegin
; P% g8 G' v7 @; ~. h# ] SaveCurrentPosition := FileStream.Position;6 Y4 e9 [& c! @9 O
SaveFile := TFileStream.Create(FileName, fmCreate);6 W8 Z; |. V7 j6 c+ c" I% W8 n/ ~
try
( V9 c6 p# I/ N$ k; l6 }; j/ q- ^ FileStream.Position := FileOffset; Z/ i5 w0 w0 j+ G) U
SaveFile.CopyFrom(FileStream, FileSize);
: h! U" L4 J1 A5 P6 ~ finally" V+ V6 T* F( y. M/ d
FileStream.Position := SaveCurrentPosition;3 U& |- V! Q# Y4 F% j% V
SaveFile.Free;
3 K# \/ w" m! ^5 j4 m8 t4 O end;
1 i; a7 I( Y- T" `* q0 g1 zend;. o, l7 Y9 q8 B
8 }7 ^/ q* v$ c! |* I+ |( N. e s
function ReadArchive(filename: String): boolean;2 G8 ]* D5 l3 T, }
const
/ t6 V8 w2 g/ h6 G2 _2 J3 G4 d- z Signature = 'CryoBF - 2.02.0';' `: t1 F/ z! q
var4 e4 [6 S- d% o
f: TFileStream;
% J" B8 E" m$ `+ R6 m! r FolderOffset, FirstFileOffset," T' A# r/ L4 ~ j; j
ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
+ R5 ]0 D: E8 C% g) ~, P4 m0 F TempString, FolderName, ObjectName: String;
8 P% y% [; g0 ]/ J s0 l; r' {1 f% B" y! N0 j1 q, k
procedure GetFolderContent(CurrentRootNode: TTreeNode);6 h/ b# g, v$ e7 k/ [. I9 x
var
* h7 _0 o% l+ _$ n& x4 `( ], U, z i, NumberOfObjects: Cardinal;7 X3 h* J4 Q$ z5 W. w8 Z
currentNode: TTreeNode;
R. S+ z4 z9 `& H1 z& p begin0 u7 b% \& f" i9 o3 r1 ?; l" e
/// Создаем текущую папку и переходим в нее
H" P9 C. o. @+ Z /// CreateDir(FolderName);
& d2 U7 j& {" J /// ChDir(FolderName);
, A; Y J% Y# n1 J, w! k0 a: `7 s, `1 l: K
// Создаем ветку в дереве
9 Q0 F$ o" j; n% N0 G TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';
5 W3 B" Q* K& {3 ?- I. W7 v% N currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);; J# M; ]* E; k9 j8 K/ ~0 E; I
' q5 ]) `/ ]1 s/ x5 ^ // Читаем кол-во обьектов
' h& ]+ f0 I: A! x0 O4 x9 X& [ f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
+ @. ~ q; {/ t [% b1 ?
. h) l$ g5 r3 j/ L# X // Проходи по всем обьектам1 Z+ t2 \; @8 ?3 p/ ]4 @. _2 z6 N
for i := 1 to NumberOfObjects do begin1 u- A( n3 c8 R2 k' ]8 U \
// Читаем имя обьекта
7 X7 J k9 ], s% I W! n f.Read(ObjectNameLength, SizeOf(ObjectNameLength));+ G5 f( o! U1 } l
SetLength(ObjectName, ObjectNameLength);
u& X3 D9 N8 d/ i- m f.ReadBuffer(ObjectName[1], ObjectNameLength);
& h/ E1 r# u/ p$ L% r* | // Узнаем тип обьекта- x( q4 n8 e# Y3 a- \
f.Read(TypeOfObject, SizeOf(TypeOfObject));. n1 Q8 C3 T. {
// Если это папка, то7 {1 l8 I. S4 K# ~, I, k( R
if TypeOfObject = 1 then begin) h( B; i- y9 q/ q0 S
FolderName := ObjectName;6 {& V) V) N; w7 N
// Проходим по ее содержимому
4 d/ t2 k3 r( x3 K! a! k I GetFolderContent(currentNode);; m: L3 G; m$ P" V6 S; m( }5 ^
0 Z7 z1 b; G" h5 X2 h /// Выходим из вложенной папки; ~# R/ E6 D1 V- I$ Q
/// ChDir('..');( R0 V4 n$ a$ J" s- m
end# A. b# } |0 U: X* d) n
// Если это файл, то
. t% G" I) p) R2 ]4 n1 s0 F( ] else begin
4 k9 A6 V( W6 N9 Y/ a5 y // Читаем его размер' h& X$ t% d& B' L
f.Read(FileSize, SizeOf(FileSize));
% a v b, s# ], T' W# s4 a* u5 [, Q // Пропускаем 4 байта нулей1 t9 ?+ @% }$ s" Y
f.Position := f.Position + 4;# p" V( D/ f2 k- x3 k" b
// Читаем смещение этого файла.: |/ F! E! m$ [2 e
// Не забываем, что это смещение относительно FirstFileOffset,
3 `9 r) O7 D0 ^& U3 G9 ?/ J4 z5 s // а не начала файла!* }! {7 j, b) T8 U w( @4 P
f.Read(FileOffset, SizeOf(FileOffset));$ Z/ ` l& j8 [! K$ A& Q! E9 h
; B% a7 p& u! X, G2 n // Создаем в дереве соответв. ветку о файле
; M; d X k, f, T, i( T' { TempString := 'Размер: ' + IntToHex(FileSize, 8) +5 i0 X4 t2 |6 K) h: d: \
'; Смещение: ' + IntToHex(FileOffset, 8) +* z% E' L& l; b4 H: {8 f
'; Имя: ' + ObjectName;' q3 @) U1 J& W- k3 P, D
Form1.TreeView1.Items.AddChild(currentNode, TempString);
4 @3 C E6 ?7 q6 L# k0 D8 y+ ?. M# Y/ Z, o1 X5 n! ~& O
/// Создаем соответв. файл. Т.е. распаковываем.
3 Z7 d9 k$ n9 u6 K8 O /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
7 q) n& h2 x. T* a) \6 F end;
; I* T+ H8 h" d c end;1 I1 ]$ y" s) f) v: W% E! d
end;# u7 S: j' E- V0 s2 J' Q
$ B. D" Q, y5 z5 j; Y: A+ D5 g9 m9 O% S x0 n' h
begin5 x1 h4 V7 o& o( p; q3 J/ \5 k
Result := false;( W6 w: ]4 F4 u$ V
// Открываем файл архива для чтения4 f& O. i3 Q) e4 z
f := TFileStream.Create(filename, fmOpenRead);
& C9 t2 X, }/ x try% U: c5 R; E* }* S5 H2 i+ P r3 {2 X
// Проверяем сигнатуру файла :) На всякий случай!& l+ _. m* U6 ^8 e9 ?9 G
SetLength(TempString, Length(Signature));
3 `6 K* y! C1 u0 [5 z f.ReadBuffer(TempString[1], Length(Signature));
4 I( @7 p! ^1 S+ N4 ^ if TempString <> Signature then Exit;
0 z4 r( c* B8 F: s! u d3 t! ~) D# i/ ~' k
// Пропускаем 9 "не нужных" байтов
8 G" q* X/ k: i/ X f.Position := f.Position + 9;
( E" w3 d( W1 I; c% L) D& } // Читаем смещение корневой папки
: `0 ?5 V, p; X+ k( I f.Read(FolderOffset, SizeOf(FolderOffset));% g- J- P2 C0 d* z& f! Z# U
// Читаем смещение первого файла( y- x& A+ B; ^7 ?# U7 V& {
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
1 z8 {/ j; Y5 O/ ?. N j6 R4 u, k // Переходим к корневой папке! K# @& ^3 {" Q/ T8 x
f.Position := FolderOffset;
9 P6 i& J5 [3 y7 L3 U
; F& c3 | b- n1 u+ H Z /// Переходим в папку в которой будем расспаковывать архив
& D/ D: t2 `" [ /// ChDir(ExtractFileDir(filename));. ?0 B. l6 P, M H5 K
9 a5 S% v9 G$ S" a5 ~. R/ W
// Корневую папку назовем по имени файла
/ W0 s* P8 [9 @' X0 N' x2 _ FolderName := (ExtractFileName(ChangeFileExt(filename,''))); ?6 C3 [" S. D$ j0 `
' j& \: y; D0 k0 o, o. x, W // Начинаем обход корневой папки
& ~" `& a. C+ r1 p GetFolderContent(nil);
) M* c8 i' j$ Y2 Z" ]. K3 T
+ `0 L; m& p5 E. V' c) F& c Result := true;
+ i/ V7 e$ _. `8 v: r4 R8 X2 Y finally
3 D4 u" j! e E( W. v5 ` f.Free;, E) y1 G5 F* s/ ^. r3 s h' d0 p
end;
+ R2 a$ u& @' Q5 g- Mend;
$ k% A: P, |% F8 L) ^) c
( V0 t+ m2 p7 ?. m7 x6 [procedure TForm1.Button1Click(Sender: TObject);8 o$ U$ w2 V9 F$ W6 @2 H( S
begin
$ {& C! w, K5 r% Y. G1 \ if OpenDialog1.Execute then begin
, ~ l- i3 s: l3 }& [' s; ^ TreeView1.Items.Clear;8 {2 o' H, U. n2 e- B* Q
TreeView1.Items.BeginUpdate;
' K g" a! H9 z9 \8 W w. M try
. v/ ?9 G7 g2 B2 ~ w: A# V$ k if ReadArchive(OpenDialog1.FileName) then: ?+ O5 X A7 p/ C
// Все нормально) E1 Z$ v3 h- c( {2 N3 d8 W; }
else6 ^0 i D8 f. J1 Z' }9 U. G
// Какая-то ошибка;
, e2 @0 m( o; U finally7 p( F' E+ M9 f
TreeView1.Items.EndUpdate;
' j. J6 ?$ z1 N end;. {. [+ E7 ~3 L) i; ~) I
end;
9 V# X0 J6 H. ?) bend; |