powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Распаковка многотомного ZIP архива
24 сообщений из 49, страница 2 из 2
Распаковка многотомного ZIP архива
    #39154068
NapalmRain
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предыдущая ошибка касалась, как выяснилось, функции GetFileSize
Но это мелочи...
Вот катастрофически примитивный код:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
try
    showmessage('0');
    aArchive := TJclDecompressArchive.Create('D:\test\files\testarchive.zip.001');
    showmessage('1');
    aArchive.AddVolume('D:\test\files\testarchive.zip.002');
    showmessage('2');
    aArchive.AddVolume('D:\test\files\testarchive.zip.003');
    showmessage('3');
    aArchive.AddVolume('D:\test\files\testarchive.zip.004');
    showmessage('4');
    aArchive.AddVolume('D:\test\files\testarchive.zip.005');
    showmessage('5');
    aArchive.AddVolume('D:\test\files\testarchive.zip.006');
    showmessage('6');
    aArchive.AddVolume('D:\test\files\testarchive.zip.007');
    showmessage('7');
    aArchive.AddVolume('D:\test\files\testarchive.zip.008');
    showmessage('8');
    aArchive.AddVolume('D:\test\files\testarchive.zip.009');
    showmessage('9');
    aArchive.AddVolume('D:\test\files\testarchive.zip.010');
    showmessage('Extract');
    aArchive.ExtractAll('D:\test');
    showmessage('Done');
  except
    on E : Exception do
      ShowMessage(E.ClassName+' поднята ошибка, с сообщением : '+E.Message);
  end;


срабатывает по нажатию на кнопку. Выдаёт все сообщения в том числе и Done, никаких эксепшнов, ничего. И распаковки, собственно, тоже никакой...
Если у кого-то есть опыт работы с данным компонентом, буду чрезвычайно благодарен за подсказку!
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154072
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Замени TJclDecompressArchive на TJclZipDecompressArchive.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154146
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NapalmRain,

Можно еще принудительно все элементы в архиве выставить в Selected.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154156
NapalmRain
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AniskinЗамени TJclDecompressArchive на TJclZipDecompressArchive.
Да, благодарю, всё получилось, но теперь новая проблема: EIntOverflow

Если я правильно понимаю, проблема в размере архива, благо эта хрень весит 8 гигов...
Если брать более новую версию 7z.dll, которая, как я думаю, должна бы уметь работать с 64 разрядными архивами,
получаю ошибку:
Код: pascal
1.
failed to load 7z.dll



Как я понимаю, самый простой для меня способ будет всё-таки использовать некий консольный архиватор.
Если у кого-то есть мысли в этом направлении, поделитесь пожалуйста!

Заранее благодарю!
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154159
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NapalmRainЕсли у кого-то есть мысли в этом направлении, поделитесь пожалуйста
У меня есть мысль, что неплохо бы было взять в ручки дебаггер, и посмотреть, в каком же месте происходит исключение и его причины, и посмотреть, что странного происходит при загрузке 7z.dll.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154191
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AniskinNapalmRainЕсли у кого-то есть мысли в этом направлении, поделитесь пожалуйста
и посмотреть, что странного происходит при загрузке 7z.dll.

A вот нефиг грузить из х32 приложения х64 библиотеку.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39154192
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NapalmRain
Как я понимаю, самый простой для меня способ будет всё-таки использовать некий консольный архиватор.
Если у кого-то есть мысли в этом направлении, поделитесь пожалуйста!



В принципе об этом уже говорили. А что непонятного в использовании? Вызов CreateProcess() с ожиданием завершения проблема? Тогда в JCL той же уже есть готовые функции.

P.S. Насчет EIntOverflow непонятно - у JclXXXXDecompression все рабочие переменые в int64 - это еще постараться надо, чтобы на такое нарваться. И да, попробуй заменить версию 7z.dll на более новую.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39156120
NapalmRain
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterA вот нефиг грузить из х32 приложения х64 библиотеку.
Это было логичное предположение, но я скомпилировал приложение под 64 бита и ошибка не пропала.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function TJclSevenzipDecompressArchive.GetInArchive: IInArchive;
var
  SevenzipCLSID, InterfaceID: TGUID;
begin
  if not Assigned(FInArchive) then
  begin
    SevenzipCLSID := ArchiveCLSID;
    InterfaceID := Sevenzip.IInArchive;
    if (not Is7ZipLoaded) and (not Load7Zip) then
      raise EJclCompressionError.CreateRes(@RsCompression7zLoadError);
    if (Sevenzip.CreateObject(@SevenzipCLSID, @InterfaceID, FInArchive) <> ERROR_SUCCESS) // как сказал дебаггер эксепшин происходит в этой строчке
      or not Assigned(FInArchive) then
      raise EJclCompressionError.CreateResFmt(@RsCompression7zInArchiveError, [GUIDToString(SevenzipCLSID)]);
    FExtractingAllIndex := -1;
  end;
  Result := FInArchive;
end;



тогдка как переполнение Int происходит
Код: pascal
1.
2.
3.
4.
    NbIndices := ItemCount;
    SetLength(Indices, NbIndices);
    for Index := 0 to NbIndices - 1 do // вот здесь
    begin



Переменная Index имеет тип Integer я заменил её на integer64 , но ошибка осталась
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39156597
NapalmRain
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем я таки решил использовать сторонний архиватор.
Два дня тестов дали результат практически тот, который интересует.
Для использования взял последнюю версию 7z.exe

Если кому интересно, конечный вариант:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    ExtractTo('D:\test\test.zip.001', 'D:\test');
  except on E: Exception do
    ShowMessage(E.ClassName+' поднята ошибка, с сообщением : '+E.Message);
  end;
end;


Где в процедуре ExtractTo может быть два варианта

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure ExtractTo(AArchive, ADestPath: String);
var
  Cmd, Params: String;
begin
  Params:= Format('x -y %s -o%s', [AArchive, ADestPath]);
  Cmd:= '7z.exe';
  OutputDebugString(PChar(Cmd + ' ' + Params));
  ShellExecute(Cmd+' '+Params); // 1 вариант
  ShellExecuteWait(Cmd, Params); // 2 вариант
end;



Для второго варианта
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
function ShellExecuteWait(AppName, Params: String; WaitTime: Cardinal = INFINITE; ShowMode: Integer = SW_SHOWMINIMIZED): integer;
var
  ShellInfo: TShellExecuteInfo;
  ExitCode: Cardinal;
begin
  Screen.Cursor:= crAppStart;
  try
    with ShellInfo do
    begin
      cbSize:= SizeOf(TShellExecuteInfo);
      fMask:= SEE_MASK_NOCLOSEPROCESS;
      Wnd:= HWND_DESKTOP;
      lpVerb:= 'open';
      lpFile:= PChar(AppName);
      lpParameters:= PChar(Params);
      lpDirectory:= nil;
      nShow:= ShowMode;
    end;

    if not ShellExecuteEx(@ShellInfo) then RaiseLastOSError;

    if ShellInfo.hProcess <> 0 then
      try
        WaitForSingleObject(ShellInfo.hProcess, INFINITE);
        GetExitCodeProcess(ShellInfo.hProcess, ExitCode);
        Result:= ExitCode;
      finally
        CloseHandle(ShellInfo.hProcess);
      end
    else
      Result:= -1;
    Application.BringToFront;
    //SetForegroundWindow(Application.MainForm.Handle);
  finally
    Screen.Cursor:= crDefault;
  end;
end;



Вот примерно так. Всё это нагуглено, но протестировано и работает.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Распаковка многотомного ZIP архива
    #39691816
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AniskinЯ достаточно плотно ковыряюсь с 7z, пишу (в принципе, уже написано) интеграцию 7z с Проводником, что бы можно открывать 7z архивы как папки. Могу сказать следующее. В контексте формата zip cама 7z не знает ни о каких томах. 7z работает с обезличенным потоком, у которого нет имени. Поэтому в 7z нужно передавать уже готовый поток, в котором слиты воедино все тома. Я это делаю путем создания потока-посредника, который уже и реализует чтение из конкретных томов. Как это сделано в jcl - я не знаю, смотри их код.

А каким образом Вы готовите поток, в котором слиты воедино все тома? Простое слияние упорядоченных файлов в один не помогает(
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691820
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin,

Или хотя бы наводочку дайте, если не трудно. Очень требуется программно многотомник zip распаковать с помощью 7z.dll
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691841
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xJuniorAniskinЯ достаточно плотно ковыряюсь с 7z, пишу (в принципе, уже написано) интеграцию 7z с Проводником, что бы можно открывать 7z архивы как папки. Могу сказать следующее. В контексте формата zip cама 7z не знает ни о каких томах. 7z работает с обезличенным потоком, у которого нет имени. Поэтому в 7z нужно передавать уже готовый поток, в котором слиты воедино все тома. Я это делаю путем создания потока-посредника, который уже и реализует чтение из конкретных томов. Как это сделано в jcl - я не знаю, смотри их код.

А каким образом Вы готовите поток, в котором слиты воедино все тома? Простое слияние упорядоченных файлов в один не помогает(

Только сейчас понял, что я набрехал. Извинюсь за дезинформацию. По теме - есть два варианта реализации разделения zip архива на тома.

Первый - нативный zip-овский вариант. В нем дополнительные тома имеют расширение zNN, каждый том является независимым, имеет сигнатуры и т.д. В этом случае при открытии архива от callback процедуры требуется реализация интерфейса IArchiveOpenVolumeCallback. Черер этот интерфейс zip handler будут запрашивать потоки отдельных томов.

Второй - нативный 7z-овский вариант. В нем дополнительные тома имеют расширение NNN, и тома получаются простым разделением zip архива на куски. В этом случае нужно создавать общий поток, содержащий все тома архива.

(PS Поддержка нативного zip-овского варианта в 7-Zip появилась не сразу, возможно, на момент написания поста ее не было, тогда я не набрехал).
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691882
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin,

Спасибо за разъяснение!
Судя по Вашему описанию, я имею дело с первым (родным zip'овским) разделением. Из восьми томов отдельно как zip открываются только 4. Соответственно, не такие уж они и независимые (в том смысле, что отдельный том не есть отдельный zip-архив, если я правильно Вас понял).
Вам доводилось сталкиваться с извлечением многотомников с помощью 7z?
Пишу в Delphi 2007, но если есть пример реализации IArchiveOpenVolumeCallback на другом языке, буду и ему очень рад.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691897
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xJuniorПишу в Delphi 2007, но если есть пример реализации IArchiveOpenVolumeCallback на другом языке, буду и ему очень рад.А чем конкретно проблема состоит? У вас что то уже реализовано или с нуля пишите?
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691915
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В дипломной работе должна быть возможность извлекать пусть не все, но хотя бы основные типы архивов. И я долгое время считал, что уж с zip'ом умею работать. Пока вот на многотомный архив не нарвался.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
  iStream := TFileStreamW.Create(AFilePath, fmOpenRead);
  stream7z := T7zStream.Create(iStream);
  archive := CreateInArchive(CLSID_CFormatZip);
  archive.OpenStream(stream7z);

  for iIndex := 0 to archive.NumberOfItems - 1 do
  begin
    ActualTempFile := APathToExtract + archive.ItemPath[iIndex] + archive.ItemName[iIndex];
    NormalizePathFroWin(ActualTempFile);
    if not archive.ItemIsFolder[iIndex] then
    begin
      if not DirectoryExistsW(ExtractFilePathW(ActualTempFile)) then
        if not ForceDirectoriesW(ExtractFilePathW(ActualTempFile)) then
          exit;
      iFileStream := TFileStreamW.Create(ActualTempFile, fmCreate);
      try
        archive.ExtractItem(iIndex, iFileStream, false);
      finally
        FreeAndNil(iFileStream);
      end;
    end;
  end;



Эта конструкция никогда не подводила до недавнего времени((
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691933
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вы используете JclCompression? Тогда в список интерфейсов

Код: pascal
1.
2.
  TJclSevenzipOpenCallback = class(TInterfacedObject, IArchiveOpenCallback,
    ICryptoGetTextPassword, IUnknown)



добавляйте интерфейс IArchiveOpenVolumeCallback и реализуйте его методы. Методов два - в GetStream открывайте том с переданным индексом, в GetProperty (если будет вызываться) возвращайте запрашиваемое свойство последнего открытого тома.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691971
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, я использую обёртку 7z для Delphi - модуль sevenzip.pas.
В интерфейсах используемого класса уже есть нужный
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39691975
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И даже есть заглушки под его методы.



В целом ваш совет понятен, спасибо, попробую реализовать эти методы.
Просто думал у вас уже имеется готовый код, чтобы "велосипед не изобретать".
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39692331
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin,
Первым вызывается метод GetProperty с PROPID = kpidName. Пробовал по разному передать путь к следующему (второму) тому, передать просто имя файла следующего тома, пробовал передавать путь/имя первого тома - результат всегда один, извлекаются только файлы из первого тома.
А GetStream вообще ни разу не выполняется.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
function T7zInArchive.GetProperty(propID: PROPID; var value: OleVariant): HRESULT;
begin
  case propID of
    kpidName:
      begin
        //TPropVariant(value).vt := VT_LPSTR;
        //TPropVariant(value).pszVal := 'E:\TempDel\TempDel.zip.002';
        value := 'E:\TempDel\TempDel.zip.002';
      end;
  else
  end;
  Result := S_OK;
end;

function T7zInArchive.GetStream(const name: PWideChar;
  var inStream: IInStream): HRESULT;
begin
  Result := S_OK;
end;


Может ещё какие-то идеи подкинете? Заранее благодарен...
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39692347
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xJunior,

А работа с 7z принципиальна? или главное - результат? Тогда можете попробовать компонент fwZip от Rouse_
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39692372
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
goldmi45,
Да, принципиальна. Это мощный инструмент и всё может. Надо просто научиться... Переделывать всё на fwZip не представляется возможным(
Abbrevia, кстати, тоже хорошо справляется с многотомниками.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39692428
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xJuniorAniskin,
Первым вызывается метод GetProperty с PROPID = kpidName. Пробовал по разному передать путь к следующему (второму) тому, передать просто имя файла следующего тома, пробовал передавать путь/имя первого тома - результат всегда один, извлекаются только файлы из первого тома.
А GetStream вообще ни разу не выполняется.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
function T7zInArchive.GetProperty(propID: PROPID; var value: OleVariant): HRESULT;
begin
  case propID of
    kpidName:
      begin
        //TPropVariant(value).vt := VT_LPSTR;
        //TPropVariant(value).pszVal := 'E:\TempDel\TempDel.zip.002';
        value := 'E:\TempDel\TempDel.zip.002';
      end;
  else
  end;
  Result := S_OK;
end;


Может ещё какие-то идеи подкинете? Заранее благодарен...

При запросе kpidName нужно отдавать имя того тома, который вы передали изначально в Open. Я лично передаю просто имя без пути. И я не понял, с одной стороны вы говорите, что пытаетесь открыть нативные zip тома, но на практике передаете тома вида TempDel.zip.002, т.е. нативные 7z тома, которые не требуют плясок с IArchiveOpenVolumeCallback.
...
Рейтинг: 0 / 0
Распаковка многотомного ZIP архива
    #39692512
xJunior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AniskinИ я не понял, с одной стороны вы говорите, что пытаетесь открыть нативные zip тома, но на практике передаете тома вида TempDel.zip.002, т.е. нативные 7z тома, которые не требуют плясок с IArchiveOpenVolumeCallback.

Хм, я почему-то решил, что механизм сборки томов работает одинаково, как для нативных 7z, так и для нативных zip архивов, т.е. пляски с IArchiveOpenVolumeCallback нужны всегда. Оказалось, что они нужны только для нативных zip-многотомников, как Вы и сказали.
Хорошо, что Вы обратили на это внимание.
Я подготовил нативный zip-многотомник, описал указанные два метода IArchiveOpenVolumeCallback (пока, правда, в примитивном виде), и о чудо, тома подтянулись один за другим! Всё заработало!!! Ура!!!
Огромное Вам спасибо за профессионализм и оперативные подсказки!
Мощь 7z.dll подтвердилась в очередной раз!
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Распаковка многотомного ZIP архива
    #39952299
lobbyit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi xJunior,
can you write me the code you write to implement IArchiveOpenVolumeCallback?
I'm using latest sevenzip.pas. Can you send me a diff file or make a pull request on github?
...
Рейтинг: 0 / 0
24 сообщений из 49, страница 2 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Распаковка многотомного ZIP архива
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]