原文
6 k! ]) o' R3 D% W, d5 Uhttp://pygments.org/demo/599/
$ J1 O/ \) g( c ]& r$ J/ q& y
0 s6 q+ J2 T, J/ `. sCyroBF Extract- j8 `. o" ?3 Q7 S, _
( ]! W' K7 G* q- C1 @. mUse this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native # Y+ W0 A6 f" s- W" A+ E
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. 8 f0 ]8 h1 N/ W2 y- r
Language: Delphi. Code size: 4.0 KB. 3 E4 I& D, P- w+ z1 H
2 R2 j6 l- l5 @8 K$ cprocedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
+ w# o$ @ l% I8 ], y5 G( Cvar8 F% A7 [# J; M& c
SaveFile: TFileStream;
7 o4 w6 H( g R; c) E& m: ~; ^ SaveCurrentPosition: Int64;4 S5 t# |8 \7 W: ~
begin
! {8 i7 ~! @+ c3 x% w SaveCurrentPosition := FileStream.Position;
4 f6 j/ E2 Y1 `1 Y; b: Z3 u7 Q SaveFile := TFileStream.Create(FileName, fmCreate);
9 S6 c: [7 V/ W# r' i try
! t/ q. z, C- N0 ]+ C* f FileStream.Position := FileOffset;5 a' f! ]1 r% o* e
SaveFile.CopyFrom(FileStream, FileSize);
% H# w* N; O0 V! b finally. e1 {) |- F0 @3 e; C
FileStream.Position := SaveCurrentPosition;
+ [$ O# l5 P/ Y SaveFile.Free;
6 u, a' m3 ]1 J! W# { end;
2 p" r( ~: G; Xend;" C9 Q" ~4 U) [: g5 {
) N1 L9 E5 G G3 Ufunction ReadArchive(filename: String): boolean;; Y8 U4 ~) Y7 R
const6 h# e( O/ I2 {' G% M$ w
Signature = 'CryoBF - 2.02.0';
B" h$ C$ p/ m) T' H( i$ @4 [var
9 j+ N! \! Q7 u: K f: TFileStream;
( _: \$ @5 q/ ?8 Y5 |: b$ h+ P FolderOffset, FirstFileOffset,
" H. }2 S* F/ e1 [. }. n" \; v ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;7 p8 a$ }7 r. `2 Y: D( n& h
TempString, FolderName, ObjectName: String;
* i* ^/ f- ]8 E- G* p; a7 Q0 j$ s3 P9 `$ W: H7 t# u
procedure GetFolderContent(CurrentRootNode: TTreeNode);
6 d9 Y' E ~, O2 h2 C; [ var! K9 k3 c" ?0 ?) {# O
i, NumberOfObjects: Cardinal;7 ~3 i" m: `' O4 l" v( `/ U v
currentNode: TTreeNode;
( H _9 r8 S" b- U! G$ m begin" [9 g. U6 j* H
/// Создаем текущую папку и переходим в нее0 }# f" C3 g J. |; A% U- ^
/// CreateDir(FolderName);
% x' o$ T4 `4 }% Q0 Y" g /// ChDir(FolderName);
1 e0 ~. h. }# C9 _3 H. a: y. U. R% d4 X. P- f7 s( T
// Создаем ветку в дереве
" h5 G0 [) o! O3 \$ X n TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';1 S: ?2 L6 Q5 ~/ `# Y) j
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);# l/ m4 u7 m6 s$ V! b1 o8 \: f" W
; M$ N6 T/ L+ p0 S+ o' `: \5 ^' U A
// Читаем кол-во обьектов
( k9 w7 @% l \4 W% V( l f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
2 r) I9 V, K3 z7 P! X% b7 c% t6 c) z7 x1 k- P+ T
// Проходи по всем обьектам
6 S/ C+ m! o: V; w" R for i := 1 to NumberOfObjects do begin) Z) _, M* m( `* f
// Читаем имя обьекта* h3 v0 U7 C9 x8 T8 E& D( T
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));, B8 C7 x& V+ w! w' d' \8 e
SetLength(ObjectName, ObjectNameLength);
& Q7 u# T! |' c# G& y f.ReadBuffer(ObjectName[1], ObjectNameLength);
1 X& G1 M5 _) |$ M J# S // Узнаем тип обьекта
0 d" ~7 s" j& M; @: {. o f.Read(TypeOfObject, SizeOf(TypeOfObject)); V- A" a- s" |8 t( E/ P
// Если это папка, то
: c" p3 h2 c/ T4 p% ~% Q) ?) z3 M8 t; y if TypeOfObject = 1 then begin% g8 Q. F- ?8 q$ l: ~: {/ s! p
FolderName := ObjectName;
& W* \5 u! m0 Q% h // Проходим по ее содержимому
4 \8 s5 M6 W9 a GetFolderContent(currentNode);( U+ U4 p5 i4 R' R+ _9 |; b
6 E e4 I$ w$ }$ u- q1 j! ~ A /// Выходим из вложенной папки4 H/ x8 M$ n! r; E
/// ChDir('..');
! b: D! u0 U! m- r% q5 u3 j end
' z; Q, y3 j2 @ // Если это файл, то
+ o; C( I2 ` m% V& G% T else begin
: S, v' R; Q/ e. l4 ? // Читаем его размер: ^) \2 F: Z7 F. t- H4 B' g
f.Read(FileSize, SizeOf(FileSize));
5 N$ K) K0 J8 s# {' @ // Пропускаем 4 байта нулей
5 R B" U# f M& ` f.Position := f.Position + 4;
0 N' t( A1 y @. f2 M // Читаем смещение этого файла.
: }+ x( Y0 c# d6 U+ h2 G3 Z // Не забываем, что это смещение относительно FirstFileOffset,
7 O i6 w4 Z) F0 K B n) B // а не начала файла!/ `; d8 Y, d$ y' ~3 k, j- ]+ A
f.Read(FileOffset, SizeOf(FileOffset));
6 R! L! G2 L5 d: L9 E, ~, f7 u3 U% p- i* x+ ?
// Создаем в дереве соответв. ветку о файле9 _, `$ c6 s1 }+ Q9 b2 \
TempString := 'Размер: ' + IntToHex(FileSize, 8) +
2 U# ~4 T, i( D* E; `( R '; Смещение: ' + IntToHex(FileOffset, 8) +' L/ K% n2 u+ _2 z( ~# M1 e
'; Имя: ' + ObjectName;
5 k$ K# Q% |+ v% p Form1.TreeView1.Items.AddChild(currentNode, TempString);
3 M/ w3 Q' t: W# R5 E; d5 u6 [# V) l% |1 \
/// Создаем соответв. файл. Т.е. распаковываем.
/ j7 g2 L! T' Y- W. @% X1 r6 p9 s /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);; y4 E* Y4 ~4 i$ h$ E6 E9 }) t
end;2 l- ^! ^* l; a1 \
end;5 c) N' R# I- J+ ]* M' l
end;8 c' u% {7 m$ q8 y; n. u+ N
- P$ k7 C, Y4 |1 o6 J: J/ {
7 H- V6 L. s* d
begin& B- H% e8 h r5 L
Result := false;1 l( s' q8 W" w9 u0 I5 t6 V
// Открываем файл архива для чтения
W2 l. D) V/ r9 r! k) Y f := TFileStream.Create(filename, fmOpenRead);/ f# ]9 h t3 l0 ~1 N
try; @ A; |0 m6 g1 @5 I5 D
// Проверяем сигнатуру файла :) На всякий случай!
4 p7 a7 y( H! l4 R& M% N SetLength(TempString, Length(Signature));
% g( `" l0 P2 U f.ReadBuffer(TempString[1], Length(Signature));. A1 i# A: ?' J3 r- d+ i4 K5 t
if TempString <> Signature then Exit;) c4 L6 `9 Z: z2 f
8 _) l0 a0 A! N7 y4 M
// Пропускаем 9 "не нужных" байтов) R& s b* g4 ?& z7 H+ g- h7 L$ d
f.Position := f.Position + 9;; S. k, P& R7 ]+ D7 n$ ?) \
// Читаем смещение корневой папки) M/ K& y# }" P }. s# s
f.Read(FolderOffset, SizeOf(FolderOffset));
. G. B2 s n6 o0 p: z // Читаем смещение первого файла
% S9 o0 t+ u0 {- c f.Read(FirstFileOffset, SizeOf(FirstFileOffset));+ @* `5 z1 H# n/ A; c2 q, t
// Переходим к корневой папке3 c6 A* e8 A- _3 R
f.Position := FolderOffset;
, j) h' K3 u$ Q7 p2 v* b4 I8 S5 `/ h2 E# s
/// Переходим в папку в которой будем расспаковывать архив
' U( g3 l# t4 C4 h w. g" y& f# T /// ChDir(ExtractFileDir(filename));! s, }- a2 a$ R6 Q3 D
[0 z# Z0 I6 J; l; C$ H // Корневую папку назовем по имени файла* L2 q8 P ]: j1 n" c
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));
) O6 O: N7 ?2 a6 x3 _+ i( ~4 ~6 J& E# N2 }! _
// Начинаем обход корневой папки, ^$ r' }, f8 J( E& g1 r T
GetFolderContent(nil); M2 Y& a; N; V6 Y9 O1 x0 R
. y3 ~ N8 R" J Result := true;
5 w5 Y. {/ G$ C5 a, v C finally
# s% @& |% ]. j. L& _* P$ c f.Free;. q# d1 G6 ?+ k) V y9 L. a
end;
- D4 ?. E+ F! f! ~) I ?3 Pend;( f! V2 M/ |# C* w/ q
U s6 q% i; C$ a0 w3 Xprocedure TForm1.Button1Click(Sender: TObject);& O! N) y0 {' c8 u7 U( D3 e
begin
% t5 g4 ] [- ?* T) I( L& a if OpenDialog1.Execute then begin
7 A4 L/ [3 ^$ D TreeView1.Items.Clear;2 \5 L5 K/ W* v0 q
TreeView1.Items.BeginUpdate;; Z' u9 s; f; d( |6 D7 o
try2 l+ R7 Z1 G8 N' U8 h7 d
if ReadArchive(OpenDialog1.FileName) then
6 T/ W7 S1 C) V5 w8 Y u // Все нормально
2 n5 w9 [- Y( w9 E% u4 L& R else3 S# l8 H2 z+ B4 H0 ]
// Какая-то ошибка;6 |! u2 k4 [# `( C. J; B) f* ?
finally P" `3 J1 }% z# Z# O2 ?( p
TreeView1.Items.EndUpdate;( T* _5 F- [2 u7 G
end;% |: X9 E& N* o: F; ?
end;
7 I" S# C4 e' j _end; |