Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [sevenzip] Как распаковать определённый файл из архива 7zip (http://forum.oszone.net/showthread.php?t=336992)

Painkiller 03-10-2018 12:49 2834127

[sevenzip] Как распаковать определённый файл из архива 7zip
 
Вложений: 1
Всем привет! Есть задача распаковать определённый файл из архива 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 2834238

Как всегда проблему решил сам. Вопрос решён . Нашёл модуль по новее и чуть переписал функцию и всё заработало

Iska 03-10-2018 22:34 2834240

Painkiller, тогда дело за малым осталось — привести ссылку на:
Цитата:

Цитата Painkiller
модуль по новее »

и новый код для:
Цитата:

Цитата Painkiller
чуть переписал функцию »

;).

Painkiller 03-10-2018 23:32 2834248

Цитата:

Цитата Iska
Painkiller, тогда дело за малым осталось — привести ссылку на: »

в шапке

Iska 04-10-2018 00:21 2834254

Painkiller, спасибо! Родина Вас не забудет ;)!

Painkiller 04-10-2018 00:53 2834259

Цитата:

Цитата Iska
Painkiller, спасибо! Родина Вас не забудет ! »

Одна проблема решена , а вот, если нужно распаковать папку с файлами из архива . Функция работает только с файлами . Действительно проще было все реализовать запуск через консольный 7zip с определёнными ключами + имитацию прогрессбара прикрутить . Также до сих пор я не знаю как добавить в модуль поддержку распаковки esd формата.

opel431 04-10-2018 09:33 2834305

Цитата:

Цитата Painkiller
Одна проблема решена , а вот, если нужно распаковать папку с файлами из архива.... »

В 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 2834338

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 2834355

Цитата:

Цитата Painkiller
opel431, ай -яй -яй »

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

Painkiller 04-10-2018 13:50 2834378

opel431, я не знаю как распаковать определённую папку из архива , а не целый архив . С файлом и так понятно уже, решил сам как всегда, зачем возвращаться к этому ?
Так же интересует вопрос :
Цитата:

Цитата Painkiller
как добавить в модуль поддержку распаковки esd формата. »

Цитата:

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

Это было не оскорбление, не воспринимайте вы так слова близко к сердцу.

tarakan1983 24-01-2022 12:06 2978537

Painkiller, Подскажите, при добавлении ПАПКИ в архив использую
Код:

Arch.AddFiles(SourceFOLDER,'MyFOLDER','*.*',True);
Для указания прогресса
Код:

Arch.SetProgressCallback (nil, ProgressCallback);
Как отобразить еще и прогресс упаковки каждого файла?
Т.Е. одновременно
1. Общий прогресс
2. прогресс упаковки каждого файла


Время: 23:22.

Время: 23:22.
© OSzone.net 2001-