原文/ ?' O9 t3 Q! L
http://pygments.org/demo/599/5 r5 J0 v8 z- ~2 h% O+ o5 T0 i
" H' R% t, Z$ Z5 M( T4 z3 p4 v; dCyroBF Extract. |6 E* L, ~& p. Q1 R, r
9 z6 e4 J: ]4 g3 ~
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
5 i* P7 a! |3 {1 A+ C* JSubmitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. / |- X; R& w- g: `7 o7 ^: {
Language: Delphi. Code size: 4.0 KB. 5 N4 Z. }# I7 y
& z6 K8 u# C0 N' E n- h
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
% |7 c7 V) a, E; }4 t/ O) @+ Zvar
% p, y' f% W% o# [ SaveFile: TFileStream;
6 R4 z: a0 [9 V2 A% n SaveCurrentPosition: Int64;
0 f6 W$ Z# u p; ~, g4 _) ubegin+ X$ C, p# f4 d; T+ l X! X
SaveCurrentPosition := FileStream.Position;
6 N2 |# A$ W! C SaveFile := TFileStream.Create(FileName, fmCreate);
0 b$ H' x! B( S1 G try
- r* `" o8 |/ O. t FileStream.Position := FileOffset;+ B3 [" c6 v& S0 \) f
SaveFile.CopyFrom(FileStream, FileSize);) v, |8 f1 j5 v+ T q+ w
finally n( J( A! O) H; P3 E
FileStream.Position := SaveCurrentPosition;9 V# B1 [' R2 E. |7 Y# q- G
SaveFile.Free;
6 q* o( I: R% {$ L end;3 b5 B, o/ p5 D; x7 K- G
end;. Q2 C3 U# ]7 O* E( y! J
" H5 z" X T' o/ F4 b! Cfunction ReadArchive(filename: String): boolean;
! s6 {- `# f) x1 U8 {, T5 ]6 mconst( W+ G* h: d% o& l
Signature = 'CryoBF - 2.02.0';% M3 p' r& r! A. ?, k
var
' K7 ` T2 x* J& w+ R; l, c f: TFileStream;
4 [ c# O k0 s A/ b FolderOffset, FirstFileOffset,
7 T7 E M! r6 L i# O ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;5 g( E4 I9 g7 w6 R2 D' N; ?# Q4 A
TempString, FolderName, ObjectName: String;4 y; q1 F9 C4 G" [- L& w. c
2 g% k. s k' b' a
procedure GetFolderContent(CurrentRootNode: TTreeNode);, k) \3 P& S" k# Y5 k( Q
var: E9 e, O/ |! f* ^! H" L1 j
i, NumberOfObjects: Cardinal;, N, [' U$ D2 n
currentNode: TTreeNode;3 O! T, R9 M; \
begin
; w6 [5 ?- D2 A% J) z: ?' E9 J: R /// Создаем текущую папку и переходим в нее
9 X6 z$ t0 p* @) y /// CreateDir(FolderName);! s% g* j# e' @( r" ^3 F e
/// ChDir(FolderName);
$ I7 C3 c+ M! |8 H2 ^* S) w, g* W- e9 y
// Создаем ветку в дереве+ u* b/ u- D0 E3 d( W
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';0 o. z( D/ b: l" D7 m& p
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);
+ ]1 s% c) x0 u: }+ P! `6 h: b) J* C- }
// Читаем кол-во обьектов
* E Q# x8 H+ m- L f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
+ M' s. g/ V; ]2 m% V; u. q& ?* F8 W% Q! i" A" f; A2 Q' W. M
// Проходи по всем обьектам( z& r8 ~$ y" q1 G/ M- S5 B R
for i := 1 to NumberOfObjects do begin
% a0 W: j7 l6 q! |1 i8 q5 \ // Читаем имя обьекта
5 j& n% G- V& D2 ? f.Read(ObjectNameLength, SizeOf(ObjectNameLength));: F! O! L2 z$ Z' f- i3 W! h3 P$ h
SetLength(ObjectName, ObjectNameLength);
3 I; O. x+ ~. Y2 C7 }& S f.ReadBuffer(ObjectName[1], ObjectNameLength);! P9 u5 I" I! r6 |+ p
// Узнаем тип обьекта7 S5 B" f8 ^. H8 D! z- n
f.Read(TypeOfObject, SizeOf(TypeOfObject));! z+ B; s4 Q1 c2 R
// Если это папка, то: }: q' v, }0 o9 N, X
if TypeOfObject = 1 then begin
+ A2 J; A9 i1 d FolderName := ObjectName;& i2 c; [# f, ~
// Проходим по ее содержимому
9 {2 v3 A3 J; _$ ^) ?2 D GetFolderContent(currentNode);
: f% {8 N% ?, y* ` y! G
. |! a7 u4 ~! r, U) y1 D4 @ /// Выходим из вложенной папки
9 s0 ?/ W& \6 w* f* h /// ChDir('..');, G u7 y+ R3 g# x# w
end
4 h# |+ x8 v# t // Если это файл, то
+ ~8 F+ q1 B6 f8 i' [9 B3 R3 R! } else begin, @6 S) A4 E( k$ J& S5 Q& N
// Читаем его размер
5 P* p- M) H, |; `, \4 I f.Read(FileSize, SizeOf(FileSize));
U4 T" T0 `) b: \ // Пропускаем 4 байта нулей$ z7 w" w* u3 Z9 P$ Z" i$ [
f.Position := f.Position + 4;
, R. e; g4 o9 z2 n: t* p // Читаем смещение этого файла.6 i& U/ K6 q( k9 M' c y
// Не забываем, что это смещение относительно FirstFileOffset,
( x$ m' J9 o0 M% [. ~ // а не начала файла!2 u3 B) \" \$ g9 b2 ]
f.Read(FileOffset, SizeOf(FileOffset));2 N! a) ~& a/ o( j" Q
- T7 i1 M$ m- l7 Y. N, r2 _8 c1 o) t // Создаем в дереве соответв. ветку о файле" b9 \' ~ @: h$ g9 u7 J, h7 x! f
TempString := 'Размер: ' + IntToHex(FileSize, 8) +& }8 H8 u0 b. j& P2 p
'; Смещение: ' + IntToHex(FileOffset, 8) +
/ i6 I3 _; Z/ f. O" F '; Имя: ' + ObjectName;3 z- y9 r4 y" p, s. m. A- @$ R7 j
Form1.TreeView1.Items.AddChild(currentNode, TempString);- k( _& p8 c8 _: T' _ P6 d
; g9 b& k/ h( i9 [ /// Создаем соответв. файл. Т.е. распаковываем.& v; _. m, V& f
/// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
6 Y9 X) y; [3 e7 Y, P$ o end;+ n, {) m0 |$ @2 w" E
end;0 {+ ]0 a: h4 V" ]
end;9 n1 J3 f3 O8 w6 O% I
- K- ^5 I1 h) j4 `; @, l1 n
9 ^4 `8 m- |& R( h8 gbegin
. q0 ~; [: Z3 A" {7 e Result := false;
6 D7 M [: v, O* J' [8 R. e$ e // Открываем файл архива для чтения
`' P1 a) [/ Y# e: a" C f := TFileStream.Create(filename, fmOpenRead);
z0 {% x/ f+ k1 d" s! K% X0 c/ n try- |( ]. H3 m- i
// Проверяем сигнатуру файла :) На всякий случай!
$ Q, o& b: B% R; P: A SetLength(TempString, Length(Signature));
: t0 |$ O) C& _; Z; d f.ReadBuffer(TempString[1], Length(Signature));, G2 d: a2 Q% T' Z/ P' s6 S8 }3 b
if TempString <> Signature then Exit;% t+ k1 s2 P( D8 y
Y; ?( }! Y! H4 A" W% \0 O1 K // Пропускаем 9 "не нужных" байтов
0 O3 T) Q+ |- C F7 ] f.Position := f.Position + 9;
) U, Y* k% A" @; [! [# N+ Y // Читаем смещение корневой папки
; O6 S4 H( M* v0 C! ~; o f.Read(FolderOffset, SizeOf(FolderOffset));9 a6 W0 b9 k3 F4 @! ^* x- B5 q& o0 C Q
// Читаем смещение первого файла" ^9 t, L. {" b9 |+ w' v0 j
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
7 h! b7 q1 ]( d7 T // Переходим к корневой папке h# e. a- t( ]$ g, x
f.Position := FolderOffset;
! \* o/ O! V9 `5 C$ @, r$ i) V& {
, q! I" B+ k. p8 R$ v5 c- D /// Переходим в папку в которой будем расспаковывать архив$ x3 u! A- R7 p" v
/// ChDir(ExtractFileDir(filename));
+ h2 n. `4 Q/ J' U) m2 h' ^' F) t& {$ `; n9 x7 H# G5 B9 S
// Корневую папку назовем по имени файла
6 E8 C% P# i: ~ FolderName := (ExtractFileName(ChangeFileExt(filename,'')));
7 I1 C# L# p$ ?, s$ O. s
" C! g( r/ o" l# O' U // Начинаем обход корневой папки
3 ]- K7 Y! B7 q9 l7 I GetFolderContent(nil);) f$ e& ?* F$ E; ^
. K3 ^% B4 A: [% A9 a4 y
Result := true;5 G; {. p) w4 T" U; s+ S
finally
7 Y ]$ l7 h# g0 o" \6 j6 T f.Free;
* X" l6 j2 i# v end;' S% L, f5 c& H* r3 b0 C. o6 b% A
end;
, a! V% d, p* k' K% W4 m! o/ f% H
: n+ y7 E/ ^( I4 I2 z* ~procedure TForm1.Button1Click(Sender: TObject);8 T% O' i* v" F
begin
. s2 {9 j# M) a- }$ }2 n if OpenDialog1.Execute then begin9 L" H- B6 ?0 t) a: h
TreeView1.Items.Clear;1 v& G. S% A0 U& G* h
TreeView1.Items.BeginUpdate;/ r2 c" Y! `" C
try3 l7 o9 n4 Q4 c/ p3 u, o
if ReadArchive(OpenDialog1.FileName) then0 K9 Z4 D% ^. l/ i
// Все нормально
+ R4 |: L" }: v* d' l5 g$ u else, m7 m0 g* o6 z( Y$ v& {/ f' P
// Какая-то ошибка;! E/ A/ {# I9 ]# N, S
finally
1 ^, D4 b# V* g. m! n TreeView1.Items.EndUpdate;
; h: h1 X8 M0 |/ d0 j# e8 j end;
- ^, U( g& _8 v4 ]* a end;
9 ?- i2 r1 L2 u& a1 `8 h9 Y1 s: jend; |