原文7 A* ~8 Q% s. i/ `# X9 `
http://pygments.org/demo/599/
6 P1 g/ ~5 I- h! {$ G7 c# I
) V6 L- T# \; C& u6 kCyroBF Extract# \$ w, ]. u! J$ U0 t* b/ E
) h/ P* L; z& |8 C: @/ M/ M; @Use this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native 5 J* l. J' A5 L) m8 v' B
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. 5 S+ [& O7 b3 a* m$ Q' G, ]
Language: Delphi. Code size: 4.0 KB. . D- Z7 R* |: _. C( r
1 _4 o9 k4 |4 W2 { |% `; F
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
$ K' F( m! x; d# |3 Bvar* y6 o- Y ~$ j" p5 M
SaveFile: TFileStream;- D6 V9 U, c" a3 x4 a
SaveCurrentPosition: Int64;
5 f; D; O' i M" K7 ?! Wbegin1 u: m& V7 p+ U( `+ F, S5 k
SaveCurrentPosition := FileStream.Position;
2 a/ J; W& C; T SaveFile := TFileStream.Create(FileName, fmCreate);% |; J2 g1 W1 r, ?
try3 e# E) f% \+ S1 e
FileStream.Position := FileOffset;
8 Y7 M$ f, |" a2 j8 L/ l% h SaveFile.CopyFrom(FileStream, FileSize);0 A( H' w. `5 {
finally* P0 C- w2 ~, K, z7 h6 G; p4 K
FileStream.Position := SaveCurrentPosition;
/ Q# T: w, Q" | SaveFile.Free;: z' Q! v( D& u
end;
; X) S" ] U' oend;. U4 ^ f6 x/ y' `! |0 t
" a( p4 x2 R( w- }1 e! \. ?( ]' ffunction ReadArchive(filename: String): boolean;5 Z/ ~" {& s* r8 L0 q
const
6 U: g% M. K. g! L* Z) a" H' E Signature = 'CryoBF - 2.02.0';
4 w$ a3 e7 o3 r, }+ qvar* D% h+ y$ f8 `8 q- R j
f: TFileStream;) U& v9 T' o+ H! ^. `
FolderOffset, FirstFileOffset,
: N. e) ~, d5 R- P ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
7 i) @' r0 [3 ?, [# f! D( x* }! g TempString, FolderName, ObjectName: String;5 s+ R& p( e, e$ u
% ~8 M+ t! t) q+ d- P8 ^5 W procedure GetFolderContent(CurrentRootNode: TTreeNode);
6 H* z( w) O$ @' j" o+ p/ I var
. p, X7 q. h3 J$ L i, NumberOfObjects: Cardinal;; {: @* E1 ~$ C) N$ v6 f% X
currentNode: TTreeNode;+ J/ O! f0 T+ v6 @& `' w8 e
begin$ j% s. C) J' o }! ~% g* B
/// Создаем текущую папку и переходим в нее
3 k3 a/ P; J5 O9 Q2 A /// CreateDir(FolderName);3 _% o( i$ w' V
/// ChDir(FolderName);
4 `- I, o1 a# L) r
$ X: l$ y1 `, W+ ?5 [: [ // Создаем ветку в дереве/ Z9 T' A2 O: H/ e
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')'; G s7 g+ y# G! z2 E
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);- x) [4 ~/ Q$ v
d" G' \8 L$ x
// Читаем кол-во обьектов3 A$ V p' |% i3 y4 L2 ^$ ~+ X
f.Read(NumberOfObjects, SizeOf(NumberOfObjects));, ~8 l$ A( j9 f. L: i
1 [! s) V& y8 R* t6 T$ K; G6 y // Проходи по всем обьектам2 D& @" g0 x9 z! \/ o
for i := 1 to NumberOfObjects do begin
7 U& k7 r. s7 n8 D // Читаем имя обьекта2 s7 V# N4 ?! E( v6 G. G; r
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
8 f- V2 l' {* o, S2 ]; w1 @# V' h SetLength(ObjectName, ObjectNameLength);
, N( ~8 b5 D' V f.ReadBuffer(ObjectName[1], ObjectNameLength);. e0 y% M5 f5 X* A
// Узнаем тип обьекта
% \, ^* h. W. e: Z5 C2 ] f.Read(TypeOfObject, SizeOf(TypeOfObject));
3 N X; @+ b! p6 a$ G& m4 v: [ // Если это папка, то
+ A1 ~9 R) [) g8 I if TypeOfObject = 1 then begin
( l8 H% Q% M# b0 d U- Y! T& |% i FolderName := ObjectName;
! @; {4 D4 t# [- ] // Проходим по ее содержимому) q! }! a, I& @; U$ v
GetFolderContent(currentNode);
# ]. D4 ]* v4 U+ d9 T
% H' [/ ~- L0 z9 Y! p /// Выходим из вложенной папки
8 l- k1 h& a$ q( g8 c( g! j* L; i /// ChDir('..'); M( }6 c3 |$ m n
end
: C6 E+ y. G" j // Если это файл, то
4 n ^# X1 u" U& w else begin- e. ^4 \, H( D3 ^
// Читаем его размер
3 U) V. ?+ j' K4 c' k" x4 ` f.Read(FileSize, SizeOf(FileSize));
7 E( r/ H" L: T; Q // Пропускаем 4 байта нулей" t L, c4 B9 `0 H) {% X
f.Position := f.Position + 4;8 S5 m, V% P* x3 m' ^
// Читаем смещение этого файла.
. Q5 x. o: L) V$ B // Не забываем, что это смещение относительно FirstFileOffset,
8 x! F/ J; i9 l5 f // а не начала файла!2 l8 W* m4 W2 X2 m b2 O
f.Read(FileOffset, SizeOf(FileOffset));
) O* c% u7 |. c1 e6 J
5 G4 W7 ?7 @! l! | // Создаем в дереве соответв. ветку о файле; ?: C) A" R2 N5 \9 V/ _( }
TempString := 'Размер: ' + IntToHex(FileSize, 8) +& C) ~. y* T7 ?6 p2 a$ }
'; Смещение: ' + IntToHex(FileOffset, 8) +
, p2 l! I/ I; c- _4 Z '; Имя: ' + ObjectName;3 x, }- ]5 x% l6 x& E
Form1.TreeView1.Items.AddChild(currentNode, TempString);
4 t! T3 C- }$ b$ z6 z8 Z1 ]5 Y0 T5 S! ?' p* \
/// Создаем соответв. файл. Т.е. распаковываем.9 c& ]/ L) p& p/ q4 Q" g
/// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);/ v8 W% x8 C& L7 r
end;: |- w1 N3 D( @% m$ x
end;
/ d2 R# {) n3 C* }+ N2 D- O7 u end;
9 D& p# E4 o- L) h: D* F; A- a; R0 `
8 S5 i: ~5 Z$ O0 wbegin& [7 s8 M2 h- I9 l
Result := false;
/ V" K/ y$ t4 K0 t! G) G# k // Открываем файл архива для чтения
% X K0 h; R2 _1 A f := TFileStream.Create(filename, fmOpenRead);
1 z& j3 }; ]" o. G try
* t. \, U f; t6 n9 L3 P // Проверяем сигнатуру файла :) На всякий случай!) P/ ?! t/ A/ j6 `
SetLength(TempString, Length(Signature));
4 b: D- U3 [5 |: ? f.ReadBuffer(TempString[1], Length(Signature));
* W1 s- a: ^! s6 o6 x N9 D if TempString <> Signature then Exit;$ n; ?+ ]4 a. g1 }" g
% |. v$ K8 H% A% L' D+ i
// Пропускаем 9 "не нужных" байтов
6 ?) P1 @ x3 l8 m f.Position := f.Position + 9;: p. p9 k& e! [; m C7 P% w3 I% }
// Читаем смещение корневой папки
$ J8 T" P2 c! K3 _# r f.Read(FolderOffset, SizeOf(FolderOffset));, T% O; d& t/ h
// Читаем смещение первого файла( s# _. o3 [0 F$ \& R/ Y
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
- Z! F8 W5 ~) S9 {$ A, O# {' ` // Переходим к корневой папке
. ?4 e( n- l9 F1 J5 S* X: h$ ~$ } f.Position := FolderOffset;
7 F! B6 q6 J) i8 Y& R6 M+ W) r7 P( a1 X4 h
/// Переходим в папку в которой будем расспаковывать архив# F j ^6 R+ W7 h ~% b/ {7 v2 I
/// ChDir(ExtractFileDir(filename));
' A# Y# U8 @) E
9 l( m* p% @4 k5 z) K // Корневую папку назовем по имени файла
( s" w- v% O7 K FolderName := (ExtractFileName(ChangeFileExt(filename,'')));4 r' {! T2 V+ c8 V9 ^/ O
* J' W* [. _! _7 C! {
// Начинаем обход корневой папки) ^5 B2 W2 t8 O: x
GetFolderContent(nil);) ^# f$ [% u6 I* {% h: K
6 _3 [" `5 f" K s
Result := true;
2 \; g$ z! D7 ]. ^) R! @# x finally3 ]& M7 |5 T( y
f.Free;- `% R' Y! K* b! g
end;9 D. Z" Y2 k4 y# J, B4 G: H0 H2 F
end;
5 N+ v; j8 b5 i+ w/ I i, W1 x$ q3 h7 \, x/ w3 O p8 ~
procedure TForm1.Button1Click(Sender: TObject);
7 Y9 h1 j7 N; [begin, p, D; G; R+ h! C% a b% K( S4 z+ B* i
if OpenDialog1.Execute then begin
$ v* P! B. l' b( x TreeView1.Items.Clear;
) u* w/ s% A# |( s TreeView1.Items.BeginUpdate;
7 d$ ^9 X S1 n+ S% f try
" v$ B6 i0 X3 n( D' Q if ReadArchive(OpenDialog1.FileName) then
`: O% I' l, \8 u5 q9 v // Все нормально- q- M$ ~) K) X1 \6 x9 [
else
1 C2 y- q5 V- d* }1 x9 @ // Какая-то ошибка;
- H. U p$ L4 @: e3 j' ?* n finally
* O1 i' _1 J/ o E5 t TreeView1.Items.EndUpdate;; v" Y [0 n @1 Y M! D5 Z
end;
4 q9 Z0 r: ?8 f, M end;
6 P4 l" ~# \! G3 z/ }end; |