PDA

Показать полную графическую версию : [sevenzip] Как распаковать определённый файл из архива 7zip


Painkiller
03-10-2018, 12:49
Всем привет! Есть задача распаковать определённый файл из архива 7zip. Воспользовался модулем (прикрепил к теме).
Использую функцию
uses
...sevenzip, ...

function SevenZip_ExtractFile(const aInterf: I7zInArchive; const aPath: string; const aSavePath: string): Boolean;
var i, indx: Integer; fs: TFileStream; s1, s2: string;
begin Result := False; indx := -1; for i := 0 to aInterf.NumberOfItems - 1
do begin if (not aInterf.ItemIsFolder[i])
then begin
s1 := LowerCase(Trim((aInterf.ItemPath[i] + aInterf.ItemName[i])));
s2 := LowerCase(Trim(aPath));
if (s1 = s2) then begin
indx := i;
Break;
end; end; end;
if (indx <> -1) then begin
try fs := TFileStream.Create(aSavePath, fmCreate or fmOpenWrite);
try aInterf.ExtractItem(indx, fs, False); Result := True;
finally FreeAndNil(fs); end; except Result := False;
end;
end;
end;

// Пытаюсь распаковать:
procedure TForm1.Button1Click(Sender: TObject);
var Zz: I7zInArchive;
begin Zz:= CreateInArchive(CLSID_CFormat7z);
Zz.OpenFile('C:\hidcon.7z'); if SevenZip_ExtractFile(Zz,'hidcon_x64.exe','C:\3333') then begin caption:='1' end else begin caption:='0' ;
end; end; end.

И получаю всегда 0 . Ничего не распаковывает. Где я ошибся ? Ошибок при компиляции нет.

Решил проблему так :
Новый модуль прикрепил к теме .
Сам код :
uses
SevenZipIntf

function SevenZip_ExtractFile(const aInterf: I7zInArchive; const aPath: string;
const aSavePath: string): Boolean;
var
i, indx: Integer;
fs: TFileStream;
s1, s2: string;
begin
Result := False;
indx := -1;
for i := 0 to aInterf.NumberOfItems - 1 do
begin
if (not aInterf.ItemIsFolder[i]) then
begin
s1 := LowerCase(Trim((aInterf.ItemPath[i] + aInterf.ItemName[i])));
s2 := LowerCase(Trim(aPath));
if (s1 = s2) then
begin
indx := i;
Break;
end;
end;
end;
if (indx <> -1) then
begin
try
fs := TFileStream.Create(aSavePath, fmCreate or fmOpenWrite);
try
aInterf.ExtractItem(indx, fs, False);
Result := True;
finally
FreeAndNil(fs);
end;
except
Result := False;
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Zz: I7zInArchive;
begin
Zz:= CreateInArchive(CLSID_CFormat7z,'директория где лежит 7z.dl');
Zz.OpenFile('C:\sevenzip.7z');
if SevenZip_ExtractFile(Zz,'sevenzip.pas','C:\sevenzip.pas') then begin
caption:='готово' end else begin
caption:='ошибка' ;
end;
end;

Painkiller
03-10-2018, 22:14
Как всегда проблему решил сам. Вопрос решён . Нашёл модуль по новее и чуть переписал функцию и всё заработало

Iska
03-10-2018, 22:34
Painkiller, тогда дело за малым осталось — привести ссылку на:
модуль по новее »
и новый код для:
чуть переписал функцию »
;).

Painkiller
03-10-2018, 23:32
Painkiller, тогда дело за малым осталось — привести ссылку на: »
в шапке

Iska
04-10-2018, 00:21
Painkiller, спасибо! Родина Вас не забудет ;)!

Painkiller
04-10-2018, 00:53
Painkiller, спасибо! Родина Вас не забудет ! »
Одна проблема решена , а вот, если нужно распаковать папку с файлами из архива . Функция работает только с файлами . Действительно проще было все реализовать запуск через консольный 7zip с определёнными ключами + имитацию прогрессбара прикрутить . Также до сих пор я не знаю как добавить в модуль поддержку распаковки esd формата.

opel431
04-10-2018, 09:33
Одна проблема решена , а вот, если нужно распаковать папку с файлами из архива.... »
В SevenZip целый класс для этого. Код со старой заготовки...., должен работать


// ----------------------------------------------------------------------

{ распаковать архив }
procedure Unzip7z_All(aCompressFileName: string);
var
Zz: I7zInArchive;
outDir: string;
begin
Zz := CreateInArchive(CLSID_CFormat7z);
with Zz do // интерфейс архива
begin
OpenFile(aCompressFileName); // имя архива
outDir := ChangeFileExt(aCompressFileName, ''); // выходной каталог
ForceDirectories(outDir); // создать
ExtractTo(outDir);
end;
end;

{ применение }
procedure TForm1.btn1Click(Sender: TObject);
begin
Unzip7z_All(ExtractFilePath(Application.ExeName) + 'Архив.7z');
end;

// ----------------------------------------------------------------------

{ извлечь файл из архива }
Unzip7z_ExtractFile(const aCompressFileName: string;
const aOutSaveFileName: string): Boolean;
var
fs: TFileStream;
i: Integer;
InArchive: I7zInArchive;
Item: string;
begin
Result := False;

if not FileExists(aCompressFileName) then
begin
ShowMessage('File no found');
Exit;
end;

InArchive := CreateInArchive(CLSID_CFormat7z);
try
try
InArchive.OpenFile(aCompressFileName);

if InArchive.NumberOfItems > 0 then
begin
for i := 0 to InArchive.NumberOfItems - 1 do
begin
Item := InArchive.ItemPath[i];
if not InArchive.ItemIsFolder[i] then
begin
if Item = ( { 'Имя папки в архиве\' + } ExtractFileName(aOutSaveFileName)) then
begin
if FileExists(aOutSaveFileName) then
DeleteFile(aOutSaveFileName);
fs := TFileStream.Create(aOutSaveFileName,
fmCreate or fmOpenWrite);
try
InArchive.ExtractItem(i, fs, False);
finally
FreeAndNil(fs);
end;
end;
end;
Break;
end;
end;
except
on E: Exception do
begin
Result := False;
end;
end;
finally
InArchive := nil;
end;
end;

{ применение }
procedure TForm1.btn2Click(Sender: TObject);
begin
if Unzip7z_ExtractFile(ExtractFilePath(Application.ExeName) + 'Архив.7z',
'Имя файла.txt') then
ShowMessage('No found file');
end;

Painkiller
04-10-2018, 12:03
opel431, ай -яй -яй
procedure Unzip7z_All(aCompressFileName: string);
var
Zz: I7zInArchive;
outDir: string;
begin
Zz := CreateInArchive(CLSID_CFormat7z);
with Zz do // интерфейс архива
begin
OpenFile(aCompressFileName); // имя архива
outDir := ChangeFileExt(aCompressFileName, ''); // выходной каталог
ForceDirectories(outDir); // создать
ExtractTo(outDir);
end;
end;
{ применение }
procedure TForm1.btn1Click(Sender: TObject);
begin
Unzip7z_All(ExtractFilePath(Application.ExeName) + 'Архив.7z');
end;


Если на то пошло , то бы сделали так

procedure Unzip7z_All(aCompressFileName, outDir: string);
var
Zz: I7zInArchive;
begin
Zz := CreateInArchive(CLSID_CFormat7z);
with Zz do // интерфейс архива
begin
OpenFile(aCompressFileName); // имя архива
ForceDirectories(outDir); // создать
ExtractTo(outDir);
end;
end;
{ применение }
procedure TForm1.btn1Click(Sender: TObject);
begin
Unzip7z_All(ExtractFilePath(Application.ExeName) + 'Архив.7z' , 'путь распаковки');
end;


Unzip7z_ExtractFile(const aCompressFileName: string;
const aOutSaveFileName: string): Boolean;
var
fs: TFileStream;
i: Integer;
InArchive: I7zInArchive;
Item: string;
begin
Result := False;
if not FileExists(aCompressFileName) then
begin
ShowMessage('File no found');
Exit;
end;
InArchive := CreateInArchive(CLSID_CFormat7z);
try
try
InArchive.OpenFile(aCompressFileName);
if InArchive.NumberOfItems > 0 then
begin
for i := 0 to InArchive.NumberOfItems - 1 do
begin
Item := InArchive.ItemPath[i];
if not InArchive.ItemIsFolder[i] then
begin
if Item = ( { 'Имя папки в архиве\' + } ExtractFileName(aOutSaveFileName)) then
begin
if FileExists(aOutSaveFileName) then
DeleteFile(aOutSaveFileName);
fs := TFileStream.Create(aOutSaveFileName,
fmCreate or fmOpenWrite);
try
InArchive.ExtractItem(i, fs, False);
finally
FreeAndNil(fs);
end;
end;
end;
Break;
end;
end;
except
on E: Exception do
begin
Result := False;
end;
end;
finally
InArchive := nil;
end;
end;
{ применение }
procedure TForm1.btn2Click(Sender: TObject);
begin
if Unzip7z_ExtractFile(ExtractFilePath(Application.ExeName) + 'Архив.7z',
'Имя файла.txt') then
ShowMessage('No found file');
end;

Эта разве функция сможет извлечь определённую папку с файлами из архива ?

opel431
04-10-2018, 12:50
opel431, ай -яй -яй »
Ай -яй -яй, так ай -яй -яй! Вам дал пример использования класса, если понимаете о чем идет речь, рассматривая его как основу, а как Вы будете использовать свои обвертки для класса, Ваши проблемы. Так что, ай -яй -яй возьмите обратно!

Painkiller
04-10-2018, 13:50
opel431, я не знаю как распаковать определённую папку из архива , а не целый архив . С файлом и так понятно уже, решил сам как всегда, зачем возвращаться к этому ?
Так же интересует вопрос :
как добавить в модуль поддержку распаковки esd формата. »

Ай -яй -яй, так ай -яй -яй! Вам дал пример использования класса, если понимаете о чем идет речь, рассматривая его как основу, а как Вы будете использовать свои обвертки для класса, Ваши проблемы. Так что, ай -яй -яй возьмите обратно! »
Это было не оскорбление, не воспринимайте вы так слова близко к сердцу.

tarakan1983
24-01-2022, 12:06
Painkiller, Подскажите, при добавлении ПАПКИ в архив использую
Arch.AddFiles(SourceFOLDER,'MyFOLDER','*.*',True);
Для указания прогресса
Arch.SetProgressCallback (nil, ProgressCallback);
Как отобразить еще и прогресс упаковки каждого файла?
Т.Е. одновременно
1. Общий прогресс
2. прогресс упаковки каждого файла




© OSzone.net 2001-2012