原文: ]! j3 i, B) H# n8 d
http://pygments.org/demo/599// V7 J2 S- c( b l
/ y+ ^: l- A: K; o+ B( [
CyroBF Extract+ i3 O- y! t! `& R/ A3 U3 [& f
7 x! d+ N. h B7 g9 ^# @8 |, l( c: C7 s
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
8 w; k* M5 k& V' r6 |Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m.
8 r5 \5 O; X. A+ BLanguage: Delphi. Code size: 4.0 KB.
2 H1 }0 k V9 N. |$ K+ v# M0 _; K; C& l
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
6 X$ Q! w2 L' p) ^, T$ kvar$ U9 v% P9 e [+ l
SaveFile: TFileStream;
9 Y0 A' s5 F p( u' q: { SaveCurrentPosition: Int64;
" ]( B# R/ A, o: V8 I2 |9 Ebegin
/ _- h! |' j" ?$ V* N SaveCurrentPosition := FileStream.Position;
; R3 M ]0 L% j0 f- r; d SaveFile := TFileStream.Create(FileName, fmCreate);1 [ c* ?% P# i* O: o: D9 ?
try
) n9 V% u; T; c& O- ]/ w) ]& e9 x FileStream.Position := FileOffset;
, m0 X' r j% f3 G SaveFile.CopyFrom(FileStream, FileSize);
( s5 T: J0 n- `$ K' }- P/ ` finally: {% }* S; [$ Y# O( ~
FileStream.Position := SaveCurrentPosition;: c: L) h0 E0 E
SaveFile.Free;
5 p# g. B7 T5 O* ?1 I& ?) L end;7 k* P0 q2 G2 Y7 N# A% {2 q
end;8 S5 v, u5 i# S: V; ^% j* Z
+ z, I$ a2 E( _+ e! d" @- l6 C Z/ ~
function ReadArchive(filename: String): boolean;
# l' \( \; R0 C; `4 Z2 [const
- F4 R* g* |& l' `* v6 ] Signature = 'CryoBF - 2.02.0';/ O- e0 ~2 o( k
var1 m" d+ F T( _6 R, l6 r! Z
f: TFileStream;5 N# B( I) x( ]$ p0 T
FolderOffset, FirstFileOffset,; n* p6 v. w7 Z
ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
6 ~, }, |/ w/ d' c4 y' d TempString, FolderName, ObjectName: String;
# o! M! O$ P% D9 Q. X6 G( Z
- z( v) \* W3 G( |0 P p procedure GetFolderContent(CurrentRootNode: TTreeNode);
0 s( p5 O r% z9 P9 D var- S0 j2 M V& a- u( F) [
i, NumberOfObjects: Cardinal;; w/ e, a& w8 w
currentNode: TTreeNode;
& P/ [2 {5 G+ f# h8 L1 E begin# z: x2 t( O* D8 t8 f5 k s
/// Создаем текущую папку и переходим в нее
) m* g8 Q* W1 O1 _ /// CreateDir(FolderName);, s1 A4 d/ w, d
/// ChDir(FolderName);6 a: K( N+ g( ? h9 q
- ?- Z+ ]2 ]) ?0 ?2 h8 V T // Создаем ветку в дереве
' C1 J* j3 I: z" o6 f- A' A TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';7 [, M, B+ s8 P+ o* v
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);, V K/ P4 K! o" [. E% [1 T3 p
% T4 b/ D! _) ? // Читаем кол-во обьектов0 d3 Y# c- {4 D2 I9 ]; o* \
f.Read(NumberOfObjects, SizeOf(NumberOfObjects));$ T4 t& O Q* t' u$ [$ u1 E
5 t2 ?& e& v/ D2 ^3 { // Проходи по всем обьектам6 Y' a4 a1 H7 d* C5 G' ]; G
for i := 1 to NumberOfObjects do begin
) R9 O+ \! ~5 \& r; u' C8 j // Читаем имя обьекта' B0 S# W/ X$ K H4 E: [ K
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
1 H* g1 k, r! ]: {% c! V1 s3 }6 {$ k SetLength(ObjectName, ObjectNameLength);3 Y5 o. s: b8 t0 T& |
f.ReadBuffer(ObjectName[1], ObjectNameLength);0 G* W. e2 l5 k8 g
// Узнаем тип обьекта
9 x' v" z3 q" ~ f.Read(TypeOfObject, SizeOf(TypeOfObject)); e! ^8 b( S/ @% M- t
// Если это папка, то
% }3 @3 g1 S2 a/ U9 f7 t! ?' V if TypeOfObject = 1 then begin( q5 L" E: v) N1 f5 ]6 F- w
FolderName := ObjectName;! {& L4 e( A$ P4 z# f7 j
// Проходим по ее содержимому
7 i8 d: j" d y, j+ A. u: S3 e7 L GetFolderContent(currentNode);
) i% B9 r, ~4 [
: y9 v" w/ H9 Z; G /// Выходим из вложенной папки
/ W8 ~$ e0 ~/ B! x4 q /// ChDir('..');) Y- i# A2 k9 H8 C7 X4 C
end/ h6 C& O$ z7 ?6 M7 h
// Если это файл, то
' Q* B* A6 p$ L else begin
: P1 [% A, |5 Q/ s4 `; d // Читаем его размер V/ Y7 D+ @1 r% [, \: P! z7 a
f.Read(FileSize, SizeOf(FileSize));; d9 e( }5 H Y
// Пропускаем 4 байта нулей
% {* P1 K( `3 s$ \$ E+ b f.Position := f.Position + 4;
' M& T! \' M9 }$ O# ~ // Читаем смещение этого файла.: S2 T6 V: k! R+ W% h& r* ]
// Не забываем, что это смещение относительно FirstFileOffset,4 W v' r# c5 ^5 ?# u& g
// а не начала файла!; P1 K( e( F2 r1 x2 K
f.Read(FileOffset, SizeOf(FileOffset));
/ G3 k* y- t& v- F- T8 ?( n, D B4 k& f
// Создаем в дереве соответв. ветку о файле" j# W( _; K. D# y* d8 N, X6 M
TempString := 'Размер: ' + IntToHex(FileSize, 8) +
. X! r0 n& S) R H8 j '; Смещение: ' + IntToHex(FileOffset, 8) +* U. @! C* v6 x* {% R- ~
'; Имя: ' + ObjectName;2 Z6 u- B. v0 m6 _
Form1.TreeView1.Items.AddChild(currentNode, TempString);
2 C+ `3 b* `: n% F/ T( ~/ B7 X
% t- Y8 P$ [0 g* D/ N( v( G3 C3 X/ q /// Создаем соответв. файл. Т.е. распаковываем.
- n5 d7 k2 d+ c% d0 E6 B /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
6 N4 Y" e3 S' M7 ^7 t! q% P, q& m end;
9 _; q/ }, q( K- s! A% x+ T( E* ^ end;/ h9 V- I0 {* e5 k$ i
end;/ F" m, _1 ^& m) {9 U9 `
0 F( T$ x9 |) |4 G. s1 `3 J( \4 x s5 w! l
begin( [7 \; B4 d, }# [
Result := false;# a5 f/ z- i+ P8 Y, J# U/ C
// Открываем файл архива для чтения' q# U Z5 [7 a# P) \# h) Z/ g
f := TFileStream.Create(filename, fmOpenRead); U/ \, l5 H& k7 S* k
try
9 n: q) O% F( b: K // Проверяем сигнатуру файла :) На всякий случай!
: i/ w/ e$ g4 X0 J SetLength(TempString, Length(Signature));& Z3 o2 S6 T7 u
f.ReadBuffer(TempString[1], Length(Signature));3 Z+ p; y b6 K$ D( Y: c7 x; c/ A2 Q" p
if TempString <> Signature then Exit;
% q; ]7 u( A& g* c% H; T. q: ]- |
// Пропускаем 9 "не нужных" байтов- g" u) n& \5 Z/ @! L/ ~$ N
f.Position := f.Position + 9;
6 N* P8 x. i. J3 g // Читаем смещение корневой папки
& Z( C) W" i& @; ]/ F f.Read(FolderOffset, SizeOf(FolderOffset));
( k$ o9 x6 y5 N. f* X: t // Читаем смещение первого файла8 ^4 O& `. P. u2 M, M
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
5 L: r6 _' a$ B# _( \ // Переходим к корневой папке( j3 Y$ K/ G' H2 j; A4 x
f.Position := FolderOffset;& e' d9 t, d( a) v+ y
) i7 [, e( g) v5 c# _" I1 m
/// Переходим в папку в которой будем расспаковывать архив
& Q( V; }9 ^& O" L" [ /// ChDir(ExtractFileDir(filename));+ ?% i: W# b N/ f ~/ P4 m
/ _; l' Z, w5 B. Z3 p+ e$ l // Корневую папку назовем по имени файла
: H7 h' H' R4 Z9 I. v! l0 I; ^* u FolderName := (ExtractFileName(ChangeFileExt(filename,'')));/ D5 g! |' @6 A( \0 F
* D- T2 z2 N+ Q! B/ u1 R // Начинаем обход корневой папки
+ P6 c& J0 j7 ?( X/ m2 Y0 X GetFolderContent(nil);
* _- u; n* M- t- O$ R$ p3 {& }$ {# E! [ f
Result := true;- E1 G- P) A4 j9 j$ {& B0 W- P
finally
3 G) T- H; E. H8 |* a- r) T ] f.Free;
4 X0 z+ j7 u4 A; Z0 ]1 e% t/ N: R& v end;
& i2 A- i3 E5 }# j+ o/ yend;+ @* v: D' v& `6 I# U$ j4 z
) h9 _& s; A3 B8 |, u
procedure TForm1.Button1Click(Sender: TObject);
* w2 T' D# o7 s; D5 ~begin
" v, T7 l" \2 V* C7 c if OpenDialog1.Execute then begin! l. P; U h7 z% h0 q
TreeView1.Items.Clear;
+ P3 U/ c. k# v* O, { TreeView1.Items.BeginUpdate;9 ]2 d9 ]4 M- }; M: z6 [
try
' e4 I; q1 Y* U6 d; [/ ^% t- j if ReadArchive(OpenDialog1.FileName) then
& N! O; X& x2 ^$ w# D3 u. @' J+ b // Все нормально
3 \ U) T0 p. [3 _ else- {$ m# K7 `" g* A9 I4 w7 @; l
// Какая-то ошибка;
) C: ]0 ^7 ]) G- i finally' m7 z4 |9 b G: i
TreeView1.Items.EndUpdate;- {+ \) T; r$ ^: T$ Z& q
end;4 k( t% o: w& Y- H2 h
end;
& S- _+ ^+ R8 k: o: m* B" D lend; |