原文
* u! e( A L, M: F9 Lhttp://pygments.org/demo/599/
! ]5 T/ Y& Z# c5 C: |; l# I9 N Q( y/ r3 o4 c. F3 p- n
CyroBF Extract+ @; R* P% M2 Q/ ~- f( p U
" D( K5 ?- L2 A# N" l
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
6 p5 Z0 D& y7 k% o6 f; pSubmitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m.
H4 B- F$ g6 k( bLanguage: Delphi. Code size: 4.0 KB.
- {, X- I4 i# n) J% H
6 r3 C9 R/ b1 m5 |# Q% }' j& Nprocedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
0 Q# d: ^' X S R: h9 Q Cvar0 k$ V& U& M; x o/ a6 R
SaveFile: TFileStream;
* k; @4 |; X2 \ F SaveCurrentPosition: Int64;4 E5 ^' w: f# `! l9 D& ~. M3 S9 w
begin' V5 t; l5 n$ }( k" J0 j5 N
SaveCurrentPosition := FileStream.Position;
- `* I3 b! z9 }- \( K SaveFile := TFileStream.Create(FileName, fmCreate);
8 H% A& S6 y" z' x try
& @& d4 e& D$ ]# ~- h- N6 p8 f FileStream.Position := FileOffset;4 T/ _+ Y% O- I* h1 g: ]
SaveFile.CopyFrom(FileStream, FileSize);
7 q9 v& s3 s% y3 b f' e finally! E! J& c& ]% q! ^0 B+ X
FileStream.Position := SaveCurrentPosition;2 f/ N" B1 s* e- T9 A' n+ _
SaveFile.Free;
/ D2 D% [1 V7 A# f$ ` end;
y# y; c3 l1 ?" xend;& I' X+ p7 m6 G3 ?' J" a
8 a( n P5 n4 W: r! c5 Y9 o
function ReadArchive(filename: String): boolean;
5 y' H5 X* Q, @% {$ w0 g# _const
/ d4 _, l0 m7 H' B6 Z Signature = 'CryoBF - 2.02.0';
$ u: p$ L2 G uvar
9 K ~3 i1 K& V3 i- e4 |5 q f: TFileStream;" _. ^; R! C( n2 l& s
FolderOffset, FirstFileOffset,
/ s+ ]/ M# J8 }: \$ J3 F ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;5 ^. l, k# o, w: I% Q+ a9 f" s4 _" h, F
TempString, FolderName, ObjectName: String;
$ Y7 X" a+ m4 x5 j3 _' q1 X4 s8 p
. |0 A5 \* U v procedure GetFolderContent(CurrentRootNode: TTreeNode);& x4 W9 C: I4 h; e- [
var
5 B) d9 U" t- R9 x1 E0 } i, NumberOfObjects: Cardinal;6 a& P4 G: `4 I. H b5 D7 M
currentNode: TTreeNode;9 V; `+ z( d& @3 A1 ^3 A4 y
begin7 z7 {! v3 Q) L6 F! {/ M. {# }
/// Создаем текущую папку и переходим в нее
9 i- K4 Z: e) V& P( q /// CreateDir(FolderName);
: |- D& h8 d4 V" Q4 l1 p2 s /// ChDir(FolderName);+ b6 `" h/ w. W! R8 f
" s; t! K- }- G* \
// Создаем ветку в дереве8 o- X3 s8 n) H; U* t; M
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';
. x6 o- J" a4 z5 z currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);
2 T2 e: g8 {8 y# e& ? u( E
0 {6 E& V$ G6 u, [; h& g // Читаем кол-во обьектов
, B. X/ v& G( T; T f.Read(NumberOfObjects, SizeOf(NumberOfObjects));5 Y7 @8 J1 {. s! t) F
) `& q( J* X* H( p8 N' H // Проходи по всем обьектам
7 o* T* d& J" t3 K$ E5 J for i := 1 to NumberOfObjects do begin
7 V w& r) V# ^3 C // Читаем имя обьекта6 e* I7 \; @/ @% `* N/ k" F# ^
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
) N- M4 _3 F0 [) {7 t9 N% s SetLength(ObjectName, ObjectNameLength);
( g, M/ @" S, ]; b: Q* s: @ f.ReadBuffer(ObjectName[1], ObjectNameLength);
" p+ d# {: S: P+ U3 [9 V) I // Узнаем тип обьекта3 }4 b# _6 A3 j3 m7 L
f.Read(TypeOfObject, SizeOf(TypeOfObject));
+ ^% p7 i) q; E2 ]1 V, K // Если это папка, то" T- O' f7 q t2 R7 H4 |
if TypeOfObject = 1 then begin
# {2 q5 m# Q' f" T0 ~+ [ FolderName := ObjectName;& H3 Y( c s# {9 s
// Проходим по ее содержимому7 m- `" @9 M- I7 F* U' u9 V6 i
GetFolderContent(currentNode);
' _0 F' X6 W! K' l6 m3 A) ~9 f/ ]6 U/ O: C" q8 g
/// Выходим из вложенной папки
9 @; \1 A+ O* f- F( Z0 L W /// ChDir('..');5 r) n+ J* x( E0 K/ f- P
end
& A" L W" l- I // Если это файл, то
+ J7 ^+ a* |! ^+ M b; }9 p else begin
q0 X& r' n# j7 G // Читаем его размер
9 O- J/ v, t- U; I( k f.Read(FileSize, SizeOf(FileSize));
; n6 i0 Y2 L4 m" W @1 ~ // Пропускаем 4 байта нулей- D! u6 C; {% B2 h, }
f.Position := f.Position + 4;* {3 a0 ?: |0 U0 U$ E+ H
// Читаем смещение этого файла.
$ n' H0 G/ t4 @, \$ }/ o" U7 k6 T // Не забываем, что это смещение относительно FirstFileOffset,
6 ]& p* Q7 o* z m7 y6 k: S // а не начала файла!
* \! ]5 K1 o! @+ m3 } f.Read(FileOffset, SizeOf(FileOffset));4 o V/ ?- d1 ?- u# q5 v
% W) a; e) t3 W: x, R L // Создаем в дереве соответв. ветку о файле
! w& f# Y5 ^9 `) W% R3 R TempString := 'Размер: ' + IntToHex(FileSize, 8) +# \0 c4 @# B, H8 a9 h
'; Смещение: ' + IntToHex(FileOffset, 8) +
L& m6 W q; I, }/ `3 g% M '; Имя: ' + ObjectName;
$ n" J- m# Z. j2 X+ S( u: H Form1.TreeView1.Items.AddChild(currentNode, TempString);* m2 ?4 R: w& l4 V( w
/ q& N5 t/ g6 ^' W
/// Создаем соответв. файл. Т.е. распаковываем.
3 R& Y1 j& Y% t9 [ /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
4 w% C% W7 n, i/ H9 v+ P, j& \ end;
6 `/ ?- S# N f0 i# S! O end;' R4 C& g: r2 O3 j a% Q
end;
: R* ~% O4 f" U$ K0 l* T
( v% o- A$ A- c2 Z1 ]. U( {$ N5 u& j6 [+ @: F
begin
. C, [/ ?% c# y7 D+ t$ W Result := false;1 \- s' C" D( v& W% F2 o
// Открываем файл архива для чтения
! c- ^. a" r3 x. C f := TFileStream.Create(filename, fmOpenRead);
0 T7 P1 D! s) R* n6 Y/ b1 o; u o% T try6 i* l: i. M5 E! G2 k% m
// Проверяем сигнатуру файла :) На всякий случай!
: E' e8 W7 ]4 t( J6 `8 f# n SetLength(TempString, Length(Signature));# U; K! K3 Q7 }' b4 g8 n
f.ReadBuffer(TempString[1], Length(Signature));+ V) T3 T0 j" {; b; f
if TempString <> Signature then Exit;: C3 ^) R( r, |' `0 ]' j5 H9 M2 d
' M1 w- M5 C* ^' P // Пропускаем 9 "не нужных" байтов p2 y1 H/ _5 }( q8 c" ]
f.Position := f.Position + 9;! R) V9 I7 d% E4 W5 ]! y5 t
// Читаем смещение корневой папки! R' @/ B' A: P3 r
f.Read(FolderOffset, SizeOf(FolderOffset));
5 K6 W# w1 Y" P // Читаем смещение первого файла" o: {; e9 c- v; r
f.Read(FirstFileOffset, SizeOf(FirstFileOffset)); x1 j& Z% O& O h! C3 B9 {# b6 ^
// Переходим к корневой папке
2 ^9 J( Q3 `: U9 Q2 m f.Position := FolderOffset;: J- r) C; T% y3 [5 C9 o3 ?
1 r6 h8 k% F; ~1 i: l /// Переходим в папку в которой будем расспаковывать архив
, a: E q" z, d, |0 q3 R# H /// ChDir(ExtractFileDir(filename));! C( l7 P! a9 k0 y; X& T
5 X+ c( s7 S/ ]0 c' K% O: X
// Корневую папку назовем по имени файла" a( x1 A3 j; p8 p+ U
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));' O9 \. t" P2 n
* }/ w; t( N" z- ~3 w
// Начинаем обход корневой папки
' p% K) t" \. l" X4 D6 W GetFolderContent(nil);
( K6 f3 y/ B. `2 E. M( k/ p: I$ P2 ]' J$ b& a6 N
Result := true;1 J+ S: z8 F* j5 X k2 v& ]
finally
4 R8 E/ w& ~; n o) m# o f.Free;
7 w: K0 { C5 P4 v5 ~" @ end;
# j: z) Y4 X7 Q' s# S! \. [end;& D% t6 y5 T6 i
/ k, ^6 H( e, B0 U7 hprocedure TForm1.Button1Click(Sender: TObject);" F" U. e' t* N% Q
begin
" v! N) {* q/ s3 f if OpenDialog1.Execute then begin
8 q( q7 @7 ~2 x+ ]5 X! C7 } TreeView1.Items.Clear;8 u5 Z3 m: Q( S* @% T# q
TreeView1.Items.BeginUpdate;
) ?6 d% I; Q1 d! U8 O4 Y3 H try
, o4 v' }0 s5 i {6 E% @ if ReadArchive(OpenDialog1.FileName) then$ z+ @2 O9 T1 w2 f6 X: I2 y
// Все нормально2 ?3 U2 b1 P$ l, U2 j8 Q
else+ b" p1 a& [5 W4 q1 A+ y$ |/ N
// Какая-то ошибка;
; P* _& A- T( [ z, T) W finally
" G* ?; [' b) I: [; G- G TreeView1.Items.EndUpdate;
: [+ Y" j8 j0 Y: z6 ~+ G end;) D. V- O! m( ?8 ~$ G
end;7 I. @/ W+ E: I1 [
end; |