原文
! D/ ]1 F+ R) W* `% Nhttp://pygments.org/demo/599/
( g( c7 @* o5 O9 d" Z! {6 Q" M. q6 [0 \6 Z
CyroBF Extract/ X; M H! K/ i- E5 P- D% p2 }+ x" m
) D9 j. F4 V5 l" z2 M9 f% d
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
& B' w: t" M+ d* [9 b7 @- @Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. 1 Q3 O# b2 K' ~
Language: Delphi. Code size: 4.0 KB. 2 Y3 M! G! a0 _1 G$ \2 Z3 u; x
) B* U' c( w; ~6 V6 Bprocedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);1 b- f7 b" n' E! L
var7 v' R- x! Z) Q) h
SaveFile: TFileStream;
. F( o. q( v1 K6 p* j SaveCurrentPosition: Int64;; b3 x1 ~& e( {) z0 j& U! h E
begin
+ Q6 h1 s" N! x# X# I SaveCurrentPosition := FileStream.Position;9 ~' D9 B4 r- P/ m% c; I7 p" J
SaveFile := TFileStream.Create(FileName, fmCreate);$ x! E5 {9 C4 r" x$ ^
try
! [" [* U/ ]/ p3 s9 o FileStream.Position := FileOffset;
" w2 ` P1 c' [! F- H) L. f5 M SaveFile.CopyFrom(FileStream, FileSize);* c$ u! w+ O n1 c _
finally
& V7 m4 h: e. @1 Y% n) H z0 P7 l2 E FileStream.Position := SaveCurrentPosition; y' ~; v a) c& ?+ \; E+ c
SaveFile.Free;+ l5 }: f6 t8 ]9 ~+ ^# A: \% ?) X9 ~
end;
: r4 h, y9 d5 ]' Xend;. p6 K) p" t; l k- V
8 X( Z% I* I+ |& \$ S' |! Tfunction ReadArchive(filename: String): boolean;
/ v. E+ k7 [' m( Wconst
* p. f) X/ S. c' x- k Signature = 'CryoBF - 2.02.0';
8 l/ ], C3 A5 Q) [ ]6 Wvar1 k2 T# x. K; _4 ~) U
f: TFileStream;; e+ G3 y% |1 Y2 q" { J3 T! ~+ s. H
FolderOffset, FirstFileOffset,
2 ]6 R, s8 Z: Z( U( c7 ?0 }1 H ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
& |8 e1 g# G0 D& t' s TempString, FolderName, ObjectName: String;
4 |% g/ C |0 j6 V# e
- ~, n/ ^( r6 O" f- [# Z } procedure GetFolderContent(CurrentRootNode: TTreeNode);
; C. p( v, ]; }' e: O+ \) S var
' i5 z4 M, H( s" T i, NumberOfObjects: Cardinal;" M2 e" E" Z. `# ^, ~
currentNode: TTreeNode;8 a, I# o& s( k6 Y$ w
begin$ Z. ~1 P& B3 i
/// Создаем текущую папку и переходим в нее' ~5 H% z5 h! o- d+ t& K
/// CreateDir(FolderName);
% o- @, b3 J, d: K- o2 ~) w1 X /// ChDir(FolderName);4 c, ~" a+ w0 l7 V/ O7 ~% R7 ?
8 U m% ]- x0 t9 H8 }( W9 D: Y7 w // Создаем ветку в дереве3 M4 I U' q7 K' z
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';1 H! r0 @: H+ L' e+ }2 w
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);' c" Q- r- D& M% Q" h3 A
6 B! y9 D) n) O! M/ H& r // Читаем кол-во обьектов
; z% F, v! @/ ?9 @& o1 ~, c f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
8 R7 y: K: B v, Q c' I) N- t5 a/ M: a
// Проходи по всем обьектам
) g5 p( T, h5 a( S4 ^ for i := 1 to NumberOfObjects do begin
' L# w" V( _" V5 T9 x! B // Читаем имя обьекта9 P9 W0 T8 B1 n. m5 t; G, P+ Y! m
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
8 H! w2 H% H, L/ u% \5 ^ SetLength(ObjectName, ObjectNameLength);* ^" o* ], n/ g5 I0 N
f.ReadBuffer(ObjectName[1], ObjectNameLength);3 R: l+ Z. H3 O* ^1 g
// Узнаем тип обьекта
8 H! V+ v& e/ T# C3 s; K f.Read(TypeOfObject, SizeOf(TypeOfObject));* m. J4 y$ q! z
// Если это папка, то& V& @" q3 [7 C
if TypeOfObject = 1 then begin
; ` o; t( B$ z. D0 ?+ j FolderName := ObjectName;
; I, i) U, X. u7 h2 Z // Проходим по ее содержимому% B( _1 j& M& i% M
GetFolderContent(currentNode);
" b9 X0 S/ i1 P! ^. x0 L6 s* y0 D3 |" D w
/// Выходим из вложенной папки
: w0 J' T, r! s$ B: M; o ^ /// ChDir('..');2 K, A+ K5 a* V
end. M" w0 Y& Q/ A5 r2 i3 Z
// Если это файл, то% h" H- G' A$ T) {; c' I3 t
else begin( O; r( v1 t* h( t
// Читаем его размер! X0 }/ l% ?' O0 N; k7 g. N* _
f.Read(FileSize, SizeOf(FileSize));
+ E) y9 P1 w3 i7 S: O. @1 W // Пропускаем 4 байта нулей' d4 P- }' k. j: l
f.Position := f.Position + 4;
7 W9 r- B; @) _# | // Читаем смещение этого файла.
! L& h O( S* s5 R5 ~$ Z // Не забываем, что это смещение относительно FirstFileOffset, C2 J& u. B; G" J# s' P6 F$ ` B
// а не начала файла!; X7 ?* s* a, Z3 M B
f.Read(FileOffset, SizeOf(FileOffset));' \/ J9 ~4 S& j7 |( M
8 M* F, y1 C& K: P$ L- \: ] // Создаем в дереве соответв. ветку о файле
5 |3 D$ s2 x' r/ w& G5 A# g. a" z, L/ H TempString := 'Размер: ' + IntToHex(FileSize, 8) +
( H( @. a( z; A7 z) P6 K9 T '; Смещение: ' + IntToHex(FileOffset, 8) +# g3 [, T3 M. P D0 v) ] N& K* o
'; Имя: ' + ObjectName;
" V( Q; `4 c* m6 ]- L1 u Form1.TreeView1.Items.AddChild(currentNode, TempString);
3 g# F" p/ g2 |- h3 F) D" `
! r& v7 R O( N0 `0 z- E: D% U /// Создаем соответв. файл. Т.е. распаковываем.! Q) q5 L, X5 A
/// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
3 U2 X7 d9 t( W; C; |$ f3 ]( I2 o end;
, M. u- K6 \6 x& s: q end;8 E- P8 b1 e# }4 [1 h' N4 D6 h
end;# M0 l2 k4 A6 ?
- [) ]+ e8 S1 \) f) b3 ]
9 C4 P0 t& e! L* sbegin
; S4 B7 j5 x2 B6 r7 @ Result := false;4 L/ t N$ Q5 Z4 ~
// Открываем файл архива для чтения
8 ]% h4 z3 _$ [( `) q O f := TFileStream.Create(filename, fmOpenRead);
* Q- |! ?/ ?) F) F c try
8 P) z% t! a% } // Проверяем сигнатуру файла :) На всякий случай!
/ n# u' s- p; o+ G6 W, q SetLength(TempString, Length(Signature));
, h, h0 g ?: F, ` f.ReadBuffer(TempString[1], Length(Signature));
! v$ f* e; X! F' I& T/ Q3 b- }" m if TempString <> Signature then Exit;
5 q2 R+ |0 B. ?3 s2 ]9 g: \* f
/ E: _ J7 n3 K // Пропускаем 9 "не нужных" байтов, z' p9 M5 N+ d; s! g
f.Position := f.Position + 9;
2 z! h- i' D. m( ^" e4 f0 D // Читаем смещение корневой папки
% {& W" O0 Q3 [2 T; g f.Read(FolderOffset, SizeOf(FolderOffset));! M7 V" j/ ?: j2 D
// Читаем смещение первого файла$ B2 v( A5 q7 B3 c9 C" c1 I
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));4 h3 h% |* s4 s9 R
// Переходим к корневой папке
* G+ O6 Z1 M% A$ f' b$ Q% { f.Position := FolderOffset;7 R/ J( [8 X1 R3 J; X7 X" S1 P
/ E; P g' q6 K3 ]' ~7 N/ ] c /// Переходим в папку в которой будем расспаковывать архив
9 t; k% _1 m0 k0 @! K /// ChDir(ExtractFileDir(filename));
3 q$ ^$ B/ |$ U8 t4 v- t
/ g! r' v+ K+ X7 `9 @ // Корневую папку назовем по имени файла
9 u/ s( S, s6 Q( {- M9 B, D FolderName := (ExtractFileName(ChangeFileExt(filename,'')));
4 z* w- I5 D# R3 B0 n
& h+ K) a J) s Q$ W, \1 _ // Начинаем обход корневой папки
. G+ ?0 c" A$ P& j+ U9 b( p GetFolderContent(nil);
4 J: J/ s3 o1 T7 R: q6 J8 `/ ^9 t$ c& q' ?6 ]# m
Result := true;
: H- \9 e1 U) n0 ]" \ finally/ [' Y2 e9 t' v4 B. U3 T
f.Free;
* j! R, M# z0 v end;1 U1 I ^) r; L- \8 B
end;
0 V' q5 d, ~9 z; Y& [& o; ~$ O/ S! C
procedure TForm1.Button1Click(Sender: TObject);
3 d6 w! u: ~; |1 h1 X F" Jbegin$ r! @/ o( w6 H
if OpenDialog1.Execute then begin
2 w& X5 T* j" [, A8 ^& u TreeView1.Items.Clear;
" Y7 y* P# o4 s: ?; e TreeView1.Items.BeginUpdate;/ _# X0 l( V: E- b8 }. j- n
try
' }' U: T/ {, h2 e if ReadArchive(OpenDialog1.FileName) then
: `# z. R# z/ M // Все нормально- N5 t/ \ j- b; c% T6 E9 c! B
else$ Y: p; E+ R0 C! W6 g4 U
// Какая-то ошибка; P8 f, ]! D* w$ b$ M. {, m) A
finally
- ]+ ]3 \5 j( x& _$ _( M TreeView1.Items.EndUpdate;
1 J( Y1 ]) z* e* I. ~0 B# p. W end;
3 l7 C+ N1 @9 |) m, W end;4 S5 I/ P% s1 w; d2 ]8 l* [4 o
end; |