Connaissez-vous un composant libre, compatible avec Delphi 2010 strong> ou xe strud> pour gérer les archives zip (en réalité, seulement lire des articles d'archive et extraire des fichiers requis)? P >
S'il vous plaît pas de bêta. p>
J'ai pensé à Zipforge de ComponceAce, mais c'est gratuit uniquement pour un usage personnel. Aucune distribution de logiciels autorisée. P>
7 Réponses :
Vous pouvez obtenir le Turbopower Abbrevia pour 2010 à partir de: http://tpabbrevia.sourceforge.net/ p>
TURBOPOWER ABBREVIA DONNÉES COMPRESSION SEP 09 2008 Il semble ne pas être testé ni mis à jour pour Delphi 2010 :(
J'ai mis à jour l'URL depuis que la version d'AbRevia sur Sourceforge prend en charge Delphi 2010 / XE et a des tests unitaires.
Vous pouvez regarder Ceci si vous aimez 7ZIP P>
Il manque un peu d'informations sur cette page. Il y a ce lien: 7-zip.org/sdk.html mais cela ne gérer l'API à 7z.dll, et j'ai lu une interface COM 7za.dll (en d'autres termes: a une bibliothèque de type à importer)
Oui, cela est prometteur. Merci!
J'accepte cette réponse. C'est juste intéressant et utile pour moi. Merci.
J'aime le Winzip Compatible Tzipmaster pour Delphi, disponible ici: http://www.delphizip.org/ a> p>
Tzipmaster est une enveloppe VCL non visuelle
Créé par Chrisvleghert et
Ericw.engler pour son logiciel gratuit
et décompressez les dlls. P>
Ces dlls sont basées sur l'infozip
Source officielle du logiciel libre / décompression
code, mais ne sont pas équivalents à
Les DLL d'Infozip. La source infozip
Le code a été modifié pour améliorer
leur facilité d'utilisation, la puissance et
Flexibilité à utiliser avec Delphes et
C ++ Builder. P>
blockQuote>
Aussi, cette question a été couvert avant sur le débordement de la pile, qui peut générer d'autres solutions pour vous. P>
Tzipmaster (avant la version V1.79) ne peut pas être construit avec succès dans la D2009. Bien que cette version de 1.79 fonctionnera ensuite dans l'environnement Unicode, il a toujours les mêmes limitations que les versions précédentes. Il n'est pas compatible avec D2010 également ou n'est pas testé.
Zipmaster semble être maintenant compatible, au moins, je vois des bugses dans les nouvelles. Merci de suggestion!
DotNetZip est une bibliothèque de code géré (.NET), qui expose une interface COM. P>
gratuit.
Open Source
MS-Pl sous licence. P>
Mauvaise plate-forme et trop de surcharge de code pour une application DELPHI.
Si la distribution d'une DLL ActiveX avec votre projet n'est pas un problème pour vous, alors Chilkat Zip (http://www.chilkatsoft.com/zip-activex.asp) semble faire le tour. Les exemples DELPHI sont ici: http://www.example-code.com/delphi/zip. ASP P>
Si vous n'avez besoin que de décodage (développé pour Delphi 2007, pas encore testé sous Delphi 2010 / XE):
unit UnitZip; interface uses SysUtils, Classes; type EZipException = class( Exception ); TZipFileInfo = record LastModified: TDateTime; Crc32: Longword; CompressedSize: Longword; UncompressedSize: Longword; end; TZipFileReader = class private // Information about the memory mapped file FFileHandle: THandle; FFileMapping: THandle; FMappedAddress: Pointer; // Location of the ZIPfile in memory. Currently we only support memory mapped ZIPfiles without disk spanning. FStart: Pointer; FSize: Longword; // ZIP file contents FFilenames: TStrings; function GetZipFileInfo ( const FileName: AnsiString ): TZipFileInfo; public constructor Create ( const FileName: string; ZipStartOffset: Int64 = 0; Size: Longword = 0 ); overload; constructor Create ( const ResourceName, ResourceType: string; Instance: HMODULE = 0 ); overload; constructor Create ( Buffer: Pointer; Size: Longword ); overload; destructor Destroy; override; function GetFile ( const FileName: string ): TBytes; overload; function GetFile ( FileID: Integer ): TBytes; overload; property FileNames: TStrings read FFileNames; property FileInfo [ const FileName: AnsiString ]: TZipFileInfo read GetZipFileInfo; end; implementation uses ZLib, Windows; const cResourceNotFound = 'Resource not found: %s.%s.'; cResourceNotLoaded = 'Resource not loaded: %s.%s.'; cCannotOpenFile = 'Cannot open file %s: OS error: %d.'; cCannotGetFileSize = 'Cannot get file size of file %s: OS error: %d.'; cCannotMapFile = 'Cannot create file mapping of file %s: OS error: %d.'; cZipFileTooSmall = 'ZIP file is too small.'; cZipFileFormatError = 'ZIP file is invalid.'; cZipBufferInvalid = 'ZIP memory buffer is invalid.'; cUnsupportedMethod = 'ZIP unsupported compression method: %d.'; cFileNotFoundInZip = 'File not found in ZIP content: %s'; // ZIP file format records. // The generic zip file format is ( TLocalFileHeader; Name; Extra; compressed data )* ( TFileHeader; Name; Extra; Remark )* TLastHeader type TFileInfo = packed record NeededVersion: Word; // 20 Flags: Word; // 1=Text,4=extra present ZipMethod: Word; // 0=stored 8=deflate LastModified: Longword; // time in dos format or Unix Timestamp Crc32: Longword; CompressedSize: Longword; UncompressedSize: Longword; NameSize: Word; ExtraSize: Word; end; TFileHeader = packed record Signature: Longword; // $02014b50 PK#1#2 MadeBy: Word; // Version number, 20 FileInfo: TFileInfo; CommentSize: Word; // 0 FirstDiskNumber: Word; // 0 IntFileAttr: Word; // 0 = binary; 1 = text ExtFileAttr: Longword; // DOS file attributes (Archived=32) LocalFileHeaderHeadOff: Longword; // @TLocalFileHeader end; PFileHeader = ^TFileHeader; TLocalFileHeader = packed record Signature: Longword; // $02014b50 PK#3#4 FileInfo: TFileInfo; end; PLocalFileHeader = ^TLocalFileHeader; TLastHeader = packed record Signature: Longword; // $02014b50 PK#5#6 ThisDiskNumber: Word; CentralDirDisk: Word; ThisDiskFileCount: Word; TotalFileCount: Word; FileHeaderSize: Longword; FileHeaderOffset: Longword; CommentSize: Word; end; PLastHeader = ^TLastHeader; const MagicLastHeader = $06054b50; MagicLocalHeader = $04034b50; MagicFileHeader = $02014b50; type IntPtr = Longword; // NativeInt on Delphi2007 is an Int64 ?? {$if CompilerVersion < 19} procedure SetAnsiString( var S: AnsiString; P: PAnsiChar; L: Integer ); inline; begin SetString( S, P, L ); end; {$ifend} { TZipFileReader } constructor TZipFileReader.Create( const FileName: string; ZipStartOffset: Int64; Size: Longword ); begin // Open the file in question. FFileHandle := CreateFile( PChar( FileName ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 ); if FFileHandle = INVALID_HANDLE_VALUE then raise EZipException.CreateFmt( cCannotOpenFile, [ Filename, GetLastError() ] ); if Size = 0 then Size := GetFileSize( FFileHandle, nil ); if Size = INVALID_FILE_SIZE then raise EZipException.CreateFmt( cCannotGetFileSize, [ Filename, GetLastError() ] ); try // Create a file mapping of the file in question FFileMapping := CreateFileMapping( FFileHandle, nil, PAGE_READONLY, 0, 0, nil); if FFileMapping = 0 then raise EZipException.CreateFmt( cCannotMapFile, [ Filename, GetLastError() ] ); try // Get the file mapped in memory (NOTE: The offset needs to be on the memory allocation granularity of the system) // Hence we assign it it's own pointer -> todo rounding etc. FMappedAddress := MapViewOfFile( FFileMapping, FILE_MAP_READ, Int64Rec( ZipStartOffset ).Hi, Int64Rec( ZipStartOffset ).Lo, Size ); if not Assigned( FMappedAddress ) then EZipException.CreateFmt( cCannotMapFile, [ Filename, GetLastError() ] ); Create( FMappedAddress, Size ); except CloseHandle( FFileMapping ); FFileMapping := 0; raise; end; except CloseHandle( FFileHandle ); FFileHandle := 0; raise; end; end; constructor TZipFileReader.Create( const ResourceName, ResourceType: string; Instance: HMODULE ); var Resource: HRSRC; Global: HGLOBAL; begin Resource := FindResource( Instance, PChar( ResourceName ), PChar( ResourceType ) ); if Resource = 0 then raise EZipException.CreateFmt( cResourceNotFound, [ ResourceName, ResourceType ] ); Global := LoadResource( Instance, Resource ); if Global = 0 then raise EZipException.CreateFmt( cResourceNotLoaded, [ ResourceName, ResourceType ] ); Create( LockResource( Global ), SizeofResource( HInstance, Resource ) ); // Note: kb57808: SizeofResource() returns the resource size rounded up to the alignment size. end; constructor TZipFileReader.Create( Buffer: Pointer; Size: Longword ); var LastHeader: PLastHeader; FileHeader: PFileHeader; i, Off: Longword; Name: AnsiString; begin // Note the location. FStart := Buffer; FSize := Size; // Some sanity checks. if FSize < sizeof( TLocalFileHeader ) + sizeof( TFileHeader ) + sizeof( TLastHeader ) then raise EZipException.Create( cZipFileTooSmall ); if IsBadReadPtr( Buffer, Size ) then raise EZipException.Create( cZipBufferInvalid ); if PLongword( Buffer )^ <> MagicLocalHeader then raise EZipException.Create( cZipFileFormatError ); // Find the last header. Due to the alignment of SizeofResource, we need o search for it. LastHeader := Pointer( IntPtr( Buffer ) + Size - sizeof( TLastHeader ) ); for i := 0 to 31 do begin if LastHeader^.Signature = MagicLastHeader then Break; Dec( IntPtr( LastHeader ) ); end; if LastHeader^.Signature <> MagicLastHeader then raise EZipException.Create( cZipFileFormatError ); FFilenames := TStringList.Create(); Off := LastHeader^.FileHeaderOffset; for i := 0 to LastHeader^.TotalFileCount - 1 do begin // Get header if Off + sizeof( TFileHeader ) >= Size then raise EZipException.Create( cZipFileFormatError ); FileHeader := Pointer( IntPtr( Buffer ) + Off ); Inc( Off, sizeof( TFileHeader ) ); if FileHeader^.Signature <> MagicFileHeader then raise EZipException.Create( cZipFileFormatError ); // Get filename if Off + FileHeader^.FileInfo.NameSize + FileHeader^.FileInfo.ExtraSize >= Size then raise EZipException.Create( cZipFileFormatError ); SetAnsiString( Name, Pointer( IntPtr( Buffer ) + Off ), FileHeader^.FileInfo.NameSize ); Inc( Off, FileHeader^.FileInfo.NameSize + FileHeader^.FileInfo.ExtraSize ); // Save filename and offset into ZIPfile where it can be found. FFileNames.AddObject( Name, Pointer( FileHeader^.LocalFileHeaderHeadOff ) ); end; // For quick access. TStringList( FFilenames ).Sorted := True; end; destructor TZipFileReader.Destroy; begin if Assigned( FMappedAddress ) then UnmapViewOfFile( FMappedAddress ); if FFileMapping <> 0 then CloseHandle( FFileMapping ); if FFileHandle <> 0 then CloseHandle( FFileHandle ); inherited Destroy; end; function TZipFileReader.GetFile( const FileName: string ): TBytes; var ID: Integer; begin // Convert filename in FileID and access by ID. ID := FFilenames.IndexOf( FileName ); if ID < 0 then raise EZipException.CreateFmt( cFileNotFoundInZip, [ FileName ] ); Result := GetFile( ID ); end; function TZipFileReader.GetFile( FileID: Integer ): TBytes; var Off: Longword; Local: PLocalFileHeader; ZRec: TZStreamRec; const ZLibHeader: array [ 0..1 ] of Byte = ( $78, $01 ); // Deflate 32KB window size no preset dictionary. begin // Sanity check if ( FileID < 0 ) or ( FileID >= FFilenames.Count ) then raise EZipException.CreateFmt( 'Invalid File ID: %d', [ FileID ] ); // Get the file header and perform sanity check Off := Longword( FFilenames.Objects[ FileID ] ); if Off + sizeof( TLocalFileHeader ) >= FSize then raise EZipException.Create( cZipFileFormatError ); Local := Pointer( IntPtr( FStart ) + Off ); if Local^.Signature <> MagicLocalHeader then raise EZipException.Create( cZipFileFormatError ); Inc( Off, sizeof( TLocalFileHeader ) + Local^.FileInfo.NameSize + Local^.FileInfo.ExtraSize ); if Off + Local^.FileInfo.CompressedSize >= FSize then raise EZipException.Create( cZipFileFormatError ); // note: should we check the name again? SetLength( Result, Local^.FileInfo.UncompressedSize ); if Length( Result ) > 0 then case Local^.FileInfo.ZipMethod of 0: begin // STORED if Local^.FileInfo.CompressedSize <> Local^.FileInfo.UncompressedSize then raise EZipException.Create( cZipFileFormatError ); Move( Pointer( IntPtr( FStart ) + Off )^, Result[ 0 ], Local^.FileInfo.UncompressedSize ); end; 8: begin // DEFLATE ZeroMemory( @ZRec, sizeof( ZRec ) ); ZRec.next_in := @ZLibHeader; ZRec.avail_in := sizeof( ZLibHeader ); ZRec.total_in := sizeof( ZLibHeader ) + Local^.FileInfo.CompressedSize; ZRec.next_out := @Result[ 0 ]; ZRec.avail_out := Local^.FileInfo.UncompressedSize; ZRec.total_out := Local^.FileInfo.UncompressedSize; ZRec.zalloc := zlibAllocMem; ZRec.zfree := zlibFreeMem; if inflateInit_( ZRec, zlib_Version, sizeof( ZRec ) ) <> 0 then raise EZipException.Create( cZipFileFormatError ); try if not( inflate( ZRec, Z_FULL_FLUSH ) in [ Z_OK, Z_STREAM_END ] ) then raise EZipException.Create( cZipFileFormatError ); ZRec.next_in := Pointer( IntPtr( FStart ) + Off ); ZRec.avail_in := Local^.FileInfo.CompressedSize; if not( inflate( ZRec, Z_FINISH ) in [ Z_OK, Z_STREAM_END ] ) then raise EZipException.Create( cZipFileFormatError ); finally inflateEnd( ZRec ); end; end; else raise EZipException.CreateFmt( cUnsupportedMethod, [ Local^.FileInfo.ZipMethod ] ); end; // todo: CRC32 sanity check if requested. end; function TZipFileReader.GetZipFileInfo( const FileName: AnsiString ): TZipFileInfo; var FileID: Integer; Off: Longword; Local: PLocalFileHeader; begin // Get the correct file ID FileID := FFilenames.IndexOf( FileName ); if FileID < 0 then raise EZipException.CreateFmt( cFileNotFoundInZip, [ FileName ] ); // Get the file header and perform sanity check Off := Longword( FFilenames.Objects[ FileID ] ); if Off + sizeof( TLocalFileHeader ) >= FSize then raise EZipException.Create( cZipFileFormatError ); Local := Pointer( IntPtr( FStart ) + Off ); if Local^.Signature <> MagicLocalHeader then raise EZipException.Create( cZipFileFormatError ); Inc( Off, sizeof( TLocalFileHeader ) + Local^.FileInfo.NameSize + Local^.FileInfo.ExtraSize ); if Off + Local^.FileInfo.CompressedSize >= FSize then raise EZipException.Create( cZipFileFormatError ); // Return requested data. Result.LastModified := Local^.FileInfo.LastModified; Result.Crc32 := Local^.FileInfo.Crc32; Result.CompressedSize := Local^.FileInfo.CompressedSize; Result.UncompressedSize := Local^.FileInfo.UncompressedSize; end; end.
Jetez un coup d'œil à cette openSource Unité Synzip . Il est encore plus rapide de la décompression que l'unité par défaut expédiée avec Delphi et générera un EXE plus petit (les tables CRC sont créées au démarrage). P>
aucune DLL externe n'est nécessaire. P>
Je viens de faire des modifications pour gérer les noms de fichier Unicode à l'intérieur du contenu zip, non seulement Win-ansi Charset, mais également des caractères unicodes. Les commentaires sont les bienvenus. P>
Avez-vous seulement besoin de codage / décodage ou les deux?
@Ritsaert Hornstra bien, les deux, je crois.
Remarque: Démarrage avec Delphi Xe2 Prise en charge des fichiers Zip a été ajouté: [ docwiki.embarcadero.com/libries/seattle/fr/... ] [ DELPHIBLOG.TWODESK.COM/NATIVE-ZIP-FILE-SUPPORT-IN-DELPHIMPHIMPHIMHIXE2 ] Cela leur a fallu un moment!