原文
_4 _& t% ]# uhttp://pygments.org/demo/599/
7 ]' b- t/ z' C( g1 b7 b
( E! n3 E; s! B& |* ~* C7 kCyroBF Extract
2 Z/ T" ^+ o) J- L6 K/ p
1 T% m6 `+ `% [; @, aUse this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native 6 X1 n; ?/ g! ^. P, @3 w5 M
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. - S) U0 a! |8 f& e
Language: Delphi. Code size: 4.0 KB. ( m- s- U$ e. p, N
/ I _' x. t' e$ L3 ^
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
" e/ h- ?$ R9 \: \var+ z+ n9 [& J6 P, W
SaveFile: TFileStream;* E( |) i- j$ ]( C3 B
SaveCurrentPosition: Int64;, u% z. v# n; r$ ^$ E; z* R
begin' {" M. O' E! r* f O3 y
SaveCurrentPosition := FileStream.Position;. h: E$ V4 f9 d# O# X
SaveFile := TFileStream.Create(FileName, fmCreate);$ h9 S3 t& Y8 N- B8 ^
try
$ K, G; f3 I7 v0 f FileStream.Position := FileOffset;6 I: k9 x/ q+ W# v3 v
SaveFile.CopyFrom(FileStream, FileSize);0 D3 \0 A0 e2 r% ^" J5 K! Z
finally
% M; j+ |9 M$ |0 z0 V FileStream.Position := SaveCurrentPosition;8 c: \* h0 R9 e/ z7 ^0 R% A2 a4 |
SaveFile.Free;/ v) C b! Y# P. C% M4 T
end;
% r! W5 C9 I% S+ e# v) R- Hend;4 N F- }0 Y# w. N+ s
+ `; X Y/ ]. y9 K _
function ReadArchive(filename: String): boolean;
@ h" |2 q+ \6 i2 bconst
- o8 Q9 B" N/ s2 H+ t4 t Signature = 'CryoBF - 2.02.0';
8 T$ e7 h1 o0 a* V8 Qvar
7 E4 O: [! i) l6 q4 m; f! H f: TFileStream;( U- o- \0 O+ v2 k% w
FolderOffset, FirstFileOffset,5 X/ I4 ?' a T+ q4 i, ]8 m
ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;4 }; ~8 a9 [' R) y7 R
TempString, FolderName, ObjectName: String;
% s% F; s# L3 M( \% K/ G7 v$ [- D- @. C8 u8 j' h
procedure GetFolderContent(CurrentRootNode: TTreeNode); D9 P! l) D4 `& T7 u* C
var; [+ w) y+ j2 i. Z3 k
i, NumberOfObjects: Cardinal;
8 `# g* G( |% c currentNode: TTreeNode;! `5 r3 u# m/ r1 F0 w
begin6 S4 R" Q _* f$ ]# y5 j3 v, e/ h: M
/// Создаем текущую папку и переходим в нее! ^3 f2 w! |' i' B
/// CreateDir(FolderName);
) G# t: V+ e& {, U /// ChDir(FolderName);4 m- X* v Q; X* I
V/ \0 q( z0 R" j // Создаем ветку в дереве0 h% x; p& {( Y. C* c
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';+ N- A; [. X* ^' X- J
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);
1 H" L) Z# u; c+ ]6 @- j8 h# e% ]6 }$ T* r5 Q+ o1 k% t
// Читаем кол-во обьектов4 _7 n" _. R' p) @8 v' D. D
f.Read(NumberOfObjects, SizeOf(NumberOfObjects));! K7 D+ O0 \% E2 o, O% _
$ N: k, C, O: u6 b9 f2 u
// Проходи по всем обьектам, t+ F3 K# @5 J" K# g
for i := 1 to NumberOfObjects do begin
1 g/ V) k6 c, D$ y+ T // Читаем имя обьекта
% |$ X. f3 a: a/ b" _% X" y s f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
: s% }$ R% } ~: _7 G1 j SetLength(ObjectName, ObjectNameLength);
1 z; m3 v+ k4 R6 j2 B3 j f.ReadBuffer(ObjectName[1], ObjectNameLength);
# q+ k1 P! d R // Узнаем тип обьекта
1 W1 `3 _" J2 o f.Read(TypeOfObject, SizeOf(TypeOfObject));& Q. N( I J( l' Y1 U
// Если это папка, то1 S. c2 ]1 X5 {* |: K
if TypeOfObject = 1 then begin
5 I* \ x# Z/ p9 W5 x5 M0 C" U3 ] FolderName := ObjectName;+ S3 Z9 E$ T( k! o6 k+ u. U9 n4 ?
// Проходим по ее содержимому
7 k8 M6 @' S/ y GetFolderContent(currentNode);3 W, @& e" q5 j1 B0 ?$ E3 Z- G" K
& m* w5 Q' X# s' S: d
/// Выходим из вложенной папки
* q1 s7 U. ^+ l$ r( C! T7 L /// ChDir('..');, `' ]# `; M+ s' N# u
end
4 T5 m* u, F% b( g6 c // Если это файл, то7 p4 B- ?" X9 ~5 E
else begin5 f6 q0 c" w% E/ y Z
// Читаем его размер% b" Q G( `2 Q5 q/ K# l
f.Read(FileSize, SizeOf(FileSize));
) s3 [9 {/ v3 q% ]) l // Пропускаем 4 байта нулей3 z4 j7 w7 t, Y8 f& M
f.Position := f.Position + 4;
/ f+ \# E4 a: r9 T& f Z // Читаем смещение этого файла.
6 @3 w2 h8 w. K. f* }; V' e // Не забываем, что это смещение относительно FirstFileOffset,* b7 O$ Y& `- e- _/ l; E: |
// а не начала файла!
6 N' v3 v: S8 @, }# n f.Read(FileOffset, SizeOf(FileOffset));
- S% O6 l# t& Z6 O U6 F
' m" F ^2 E8 _) ^' G! v$ e# R // Создаем в дереве соответв. ветку о файле
) C3 W7 O5 E9 _3 t% d! c TempString := 'Размер: ' + IntToHex(FileSize, 8) +/ W7 b0 n( D m( O5 T' Z* u' h3 a0 p1 M+ q
'; Смещение: ' + IntToHex(FileOffset, 8) +: _0 n t8 K: h
'; Имя: ' + ObjectName;
* k: V' D) s, ^1 w* l8 F: f Form1.TreeView1.Items.AddChild(currentNode, TempString);, V% T! m/ F- D) q
4 \( T" d0 O9 ?
/// Создаем соответв. файл. Т.е. распаковываем.
% M p) p# Q3 C /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);2 E# L" N) V% X4 y& @. D" @
end;
& t) Q, V0 T1 I3 {, `% r end;
& ]4 G6 |" z% I2 A) h end;. O7 O, K z7 w+ M9 }
; f: T. e+ Z6 |. R" \
* b/ _" s. }/ Xbegin
% U* E1 X/ N5 B/ G" v Result := false;4 q" W% R9 z5 l m4 ?, z- D- b" p* x
// Открываем файл архива для чтения
8 q3 R. I3 W/ E" {2 }% |1 o$ s, c/ d" a9 \ f := TFileStream.Create(filename, fmOpenRead);) m; N/ m6 b6 J' I
try
7 H; [7 h$ x+ _4 c1 E // Проверяем сигнатуру файла :) На всякий случай!4 \3 U, k8 `, g/ ]9 f$ @
SetLength(TempString, Length(Signature));8 U! l- c1 C& d4 c2 y0 s, D% J0 ~- I
f.ReadBuffer(TempString[1], Length(Signature));! i( o5 z9 O+ r3 h
if TempString <> Signature then Exit;2 _) K2 l. k2 F5 A& Y1 d
' f2 z. X& V' z* A% J // Пропускаем 9 "не нужных" байтов7 M p. S. d7 ~3 {0 {
f.Position := f.Position + 9;
1 \" |& Y2 ]( w5 Q. _2 S5 t // Читаем смещение корневой папки
0 B8 O* ^1 m5 p! P& O# a% \ f.Read(FolderOffset, SizeOf(FolderOffset));; u! o8 Q( O3 Q
// Читаем смещение первого файла
: M, D5 B8 D, k f.Read(FirstFileOffset, SizeOf(FirstFileOffset));# w. ]3 M! @- T# l
// Переходим к корневой папке3 B- K$ D* B& a7 B* U
f.Position := FolderOffset;
! j1 F4 C& i3 _4 h2 s' S: P/ C( i$ E `
/// Переходим в папку в которой будем расспаковывать архив' K% a+ }. O! K( k6 N- b$ i& Q% ^" c5 [
/// ChDir(ExtractFileDir(filename));! X& w- y$ ?7 g. c6 y! S* H8 V# S7 z
; h+ C; r+ |! c
// Корневую папку назовем по имени файла& J* `) \$ |0 Y' D; k
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));
/ e) \( S' j- q. w' j- m
$ ^# L9 D% _3 j4 o // Начинаем обход корневой папки; T2 Q, m# U! v- o$ K+ d6 J0 o/ t9 Z
GetFolderContent(nil);, b' b" `1 W' ?
( J/ k# W, u7 X+ U" w Result := true;' l+ V1 J0 U; s2 C A6 h0 n- t3 P
finally& O/ Z" I7 z. l" R6 ^
f.Free;
o$ t: p1 q3 e" y) e8 h# X end;9 d! |8 j# ^# p. `; G5 B/ Z1 k/ R6 E F
end;
4 w2 O& n: E+ Q
6 r$ l6 C2 N8 X% |; H9 D9 U: L1 Gprocedure TForm1.Button1Click(Sender: TObject);4 v1 S, z8 { F7 T
begin3 e& p2 t5 G5 K* ~) b( O8 n
if OpenDialog1.Execute then begin
& R/ X8 B, b% ~* j" i" g( ]+ K TreeView1.Items.Clear;% o# n6 g0 f+ D d+ p) M0 J% E
TreeView1.Items.BeginUpdate;
M% S+ h* s" V6 @, l try& M% b7 ?6 Q8 {" C% g' ?$ h
if ReadArchive(OpenDialog1.FileName) then5 C! k n1 o1 f4 n/ \9 x6 ]% @% }# z
// Все нормально( j; ~% Y# L( a7 N( l c& z! w
else9 N$ l. E. q$ @
// Какая-то ошибка;; L k: V" s6 X/ e9 x' [
finally
6 k0 |; L4 O2 I0 y% Y TreeView1.Items.EndUpdate;
: A7 h$ T% `4 Q, D6 c1 {+ { end;
- [6 F8 n' K% b$ J/ a! u) B8 L end;
& x! u6 M1 z4 H; |& @, X% `% Zend; |