原文5 T6 V3 q+ p# a) i8 U' X+ D1 N7 R
http://pygments.org/demo/599/
! a+ c5 t5 P9 l
8 y; D" Y+ m5 R$ {$ YCyroBF Extract
4 [5 q: C2 U0 k( S( W9 c: @& F# c+ K6 }3 V, q' ^! c
Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
4 S7 Y: i j7 D: @, {6 fSubmitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. ; h! b6 M% o0 d; b
Language: Delphi. Code size: 4.0 KB.
( V( W" ?- q; D6 X8 Z* |& _6 }; k+ v3 G0 M7 |3 S7 |; l# \% ]
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
$ h6 [5 o( Q5 L; G4 M; A/ [var
; m: e1 t. y# d$ Q SaveFile: TFileStream;
$ _1 P6 P. |, f4 P5 n% w SaveCurrentPosition: Int64;" Z4 J: n% s; w- K/ {
begin
, F7 p7 z; ~0 ~* X5 o SaveCurrentPosition := FileStream.Position;
. }" Q1 X# Z2 g5 P9 }4 S4 m SaveFile := TFileStream.Create(FileName, fmCreate);
0 P9 g& R( \- G9 m6 P: D try: Q* |8 F/ b* \1 L \
FileStream.Position := FileOffset;
( V8 L, C/ L0 P$ m) E d' k- c SaveFile.CopyFrom(FileStream, FileSize);
U2 n0 `0 A/ I0 ^( Z& ]* w1 E5 Z finally
8 i- B1 \: h! T7 J FileStream.Position := SaveCurrentPosition;3 q5 B, l1 Y& }3 p8 M
SaveFile.Free;
2 p7 h' g: |7 [1 b- ]. R end;
4 H7 y) d+ S- D, V; kend;- ~2 q/ k0 E! l) K0 E
$ N: t: B, i& X s8 Q4 n# K
function ReadArchive(filename: String): boolean;
$ C% w& P* ]4 ^, tconst
5 F9 E- L" u: Y' R1 A0 \$ ] Signature = 'CryoBF - 2.02.0';
0 `" a8 W/ Z) p2 W6 k+ F, W- avar1 }, I1 O1 h% `7 X
f: TFileStream;
) S! c' p/ r/ D# i2 |( J FolderOffset, FirstFileOffset,& s, \. E1 \( E( C( Y
ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
' ^/ t% ?+ H! k% {: l TempString, FolderName, ObjectName: String;4 R0 ]0 ^0 s5 H3 `
" a3 c+ N( D0 ?5 @ procedure GetFolderContent(CurrentRootNode: TTreeNode);
{% G1 D( X$ f$ z' v7 ]1 z2 W2 H+ k. E var
; y8 j* U# g9 g i, NumberOfObjects: Cardinal;2 P1 b& U4 Q5 [. J. L
currentNode: TTreeNode;9 }3 s) m8 R: K9 t6 V1 ]0 Q' Z
begin/ ^% a* E. c% X/ t3 Q7 B
/// Создаем текущую папку и переходим в нее
5 h" X4 S& Z8 z8 k /// CreateDir(FolderName);3 l7 @- q& F. H) K, v! _# w
/// ChDir(FolderName); R4 j# B! f6 N2 K
+ M& S' H' v9 Q
// Создаем ветку в дереве
) `& ~) I5 q6 q7 L TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';6 G* H& j& u0 E/ l# c, U& `
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);
- ~8 P; [; E$ A" c- v
- S7 y: f# t( I3 _6 h // Читаем кол-во обьектов8 R6 D8 y3 i' _: R
f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
0 _/ _0 @1 H4 D6 Z& o# `$ M+ Q- W( `, `5 u; V7 j8 s
// Проходи по всем обьектам% s, _4 |- m1 c- K
for i := 1 to NumberOfObjects do begin
. n$ y' N3 P) v4 `$ U // Читаем имя обьекта5 w! u1 G- r0 }& ~* _ F) R
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));1 y% y' M @/ T# q3 S# |! [$ ?
SetLength(ObjectName, ObjectNameLength);( G H' W/ S, F; c/ H
f.ReadBuffer(ObjectName[1], ObjectNameLength);
* E, F* C* u6 z0 l // Узнаем тип обьекта3 t. @0 `: G! ?' J
f.Read(TypeOfObject, SizeOf(TypeOfObject));
0 M# }* u8 ?5 |8 J% Q- Z1 z // Если это папка, то
; K' o; X5 b7 a8 G4 Q if TypeOfObject = 1 then begin7 ]7 h5 S) @" Q; w
FolderName := ObjectName;
" Y0 y( b8 ?0 c // Проходим по ее содержимому U8 k( g, b* b
GetFolderContent(currentNode);) E+ n8 k' [1 }! T9 N5 n) e
6 H) w; Y) o8 s" U9 b& Q% Q" X /// Выходим из вложенной папки4 E% j# `( }4 _2 M) F6 g# @
/// ChDir('..');$ w; {/ z' O/ y0 Y9 V0 f% ?
end
# a6 K5 ]8 a( X6 G) ~: [) `. F // Если это файл, то
1 i5 p T Y( T1 w% q else begin* e* ?7 Z9 r: e. `* r
// Читаем его размер7 F( n' o! D3 d) K
f.Read(FileSize, SizeOf(FileSize));: n0 J6 x! M; J- _+ |# {: @) m
// Пропускаем 4 байта нулей
9 ]0 q* u% n& N$ R, r$ ~ f.Position := f.Position + 4;
& v9 L: ]3 s$ W // Читаем смещение этого файла.
, v% l! R6 D( S8 z1 Y // Не забываем, что это смещение относительно FirstFileOffset,
/ B& N. D% Y$ I" ~6 T // а не начала файла!, s# x0 B. m7 P1 A
f.Read(FileOffset, SizeOf(FileOffset));/ k1 _; @6 i5 J: q$ z* P/ F
/ m6 O/ ^+ T5 F) r! s; O0 z* W
// Создаем в дереве соответв. ветку о файле
) o) H& q8 m6 a$ H( E TempString := 'Размер: ' + IntToHex(FileSize, 8) +
- {- G/ o/ h6 H _9 y8 a; M$ n' v '; Смещение: ' + IntToHex(FileOffset, 8) +
7 d/ ?' N0 w+ T$ \6 [+ G '; Имя: ' + ObjectName;4 c0 [7 b1 x2 P4 C7 y0 P( D% ]
Form1.TreeView1.Items.AddChild(currentNode, TempString);
# t3 ]% \7 Y. B$ o! h4 O9 }2 H- m: H: ]: A
/// Создаем соответв. файл. Т.е. распаковываем.
- q( {2 K; K# ~- @9 F /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
5 k; L3 @: L" f+ k' s end;; a, _( V r+ ~$ j4 z9 G
end;
) z; p% o: E- g" k. Y. r' ~ end;
0 m' r# `# r7 L. t$ Z( w' H: K4 n9 `' O. b4 H/ n
0 s, |" ]; U# J; p% Y1 }3 x( e; ubegin+ J4 T& X" H) O2 c5 x& V0 q
Result := false;& [# [9 B: J/ i) _8 l
// Открываем файл архива для чтения
& P1 z& P9 h0 `$ t) p f := TFileStream.Create(filename, fmOpenRead);3 \# J' F1 c5 `" r+ {, Z% q9 M& q
try
1 y. @ W: @" K$ ?# J // Проверяем сигнатуру файла :) На всякий случай!9 `: }9 f0 A$ `+ h8 p( J' D& `1 i
SetLength(TempString, Length(Signature));
# t+ }* R! X) b# R4 b& R% p. ~+ ^ f.ReadBuffer(TempString[1], Length(Signature));
# C3 v8 f! [6 h( J3 b# P n if TempString <> Signature then Exit;; ]% c" D r* C( J/ j
1 q# v9 s& b. o* g: J8 D# k) A) C9 C // Пропускаем 9 "не нужных" байтов
6 J: g* `- r$ f1 d& o( V$ o f.Position := f.Position + 9;
3 w. X6 | m4 X: ~+ z4 j // Читаем смещение корневой папки a7 c6 t1 T1 _; F- u& s& K- B
f.Read(FolderOffset, SizeOf(FolderOffset));
& W4 v2 r0 m9 W+ X `/ c/ V) r // Читаем смещение первого файла. e( h7 S$ C5 `/ ~1 G/ E) f) D
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
7 j8 j( l5 `1 _ // Переходим к корневой папке4 I) m! m, Z9 }) Q7 P s/ h5 \
f.Position := FolderOffset;; V7 Y% p# N1 n$ _
% Y4 F# ~: \$ d /// Переходим в папку в которой будем расспаковывать архив
( {+ h: u$ @, p" Y0 N& c2 y5 U) s /// ChDir(ExtractFileDir(filename));1 R0 }% ]" ]0 q9 m! @( [9 _6 A
- [# P I3 _/ c# r$ k0 F1 p5 C // Корневую папку назовем по имени файла! b9 c `$ t# K0 H7 ]3 Q: y
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));
) g$ g/ ~7 v. l. }% ]! g+ i- X( R; W4 e- W7 s
// Начинаем обход корневой папки! Y% ?! U1 B {. i' u
GetFolderContent(nil);
+ e6 l* t0 H, b- [
: }2 G$ y! K$ G' \! D Result := true;2 @3 ^" s* k4 S5 x. F& f! Y8 I9 P
finally) m c/ a- Z! a- @( K* f
f.Free;
p8 S! s. }' s end;
, @9 n$ [6 Q5 O Fend;
# q+ ]5 x7 x: e; F ^
& b" G- ]2 R1 ?3 yprocedure TForm1.Button1Click(Sender: TObject);- N' q2 A( g' C) c2 {0 T9 b j
begin. U' ]7 I \- l" P: K; }$ F
if OpenDialog1.Execute then begin
6 z- D4 i* L' k1 Q' p" j TreeView1.Items.Clear;- d# B4 `. O0 U$ Q2 ]4 ~
TreeView1.Items.BeginUpdate;
6 ]0 N: z2 Q4 ^# h8 V0 C6 S try
' W7 K7 S# l9 g) b9 K% a( ]# O0 q if ReadArchive(OpenDialog1.FileName) then' a I8 Z* H3 ^) f! w% g
// Все нормально
/ E7 O! ?/ O- X# `0 ?8 B1 q else
# [ A: F7 f7 w c // Какая-то ошибка;9 P1 F3 q& m% R6 `
finally8 S" S9 X8 F8 L: f* f. w) i
TreeView1.Items.EndUpdate;
' E; S4 @3 Y6 C0 B9 E8 O B end;8 V1 V: V8 y+ z( b/ i U3 G% g0 g
end;4 d9 w6 R/ o1 Y9 S3 }
end; |