D7zip file list

Asked

Viewed 121 times

5

I’m using the D7zip(https://code.google.com/p/d7zip/source/) to extract files, and would like to receive the entire list of files from the archive archive. In the documentation, I found this:

with CreateInArchive(CLSID_CFormat7z) do
 begin
   OpenFile('c:\test.7z');
   for i := 0 to NumberOfItems - 1 do
    if not ItemIsFolder[i] then
      Writeln(ItemPath[i]);
 end;

That I left like this:

with CreateInArchive(CLSID_CFormat7z) do
 begin
   OpenFile('c:\test.7z');
   for i := 0 to NumberOfItems - 1 do
    if not ItemIsFolder[i] then
      FilesInZ[i] := ItemPath[i];
 end;

Of course, before I declared:

FilesInZ : array of string;

When executing, the following error occurs:

Access Violation at address 004047B0 in module 'Launcher.exe'. Read of address 00000000.

The only mistake you make is a Warning:

[Warning] LauncherUnit.pas(120): Variable 'filesinz' might not have been initialized

The line is this:

 FilesInZ[i] := ItemPath[i];

How could I solve?

  • I don’t know, the error in execution time

  • The only mistake is a Warning. I edited the post.

  • It’s all in the post, the way I declared it: Filesinz : array of string; .

  • I don’t know much about arrays in Delphi.

1 answer

4


In Delphi / Pascal, dynamic arrays are declared without a number of "spaces" for initial use

var 
  vetor: array of string;

So, if you try to add values to it before adding these "spaces" will generate an access violation error.

It is like declaring an array of defined size and trying to access an item at a position that does not exist.

var
  vetor: array[5] of string;
begin
  vetor[5] := 'Olá mundo!'; // <-- isso gera erro.

In the example, despite having informed the vector with five "spaces" of use, you need to know that the vectors start from zero position. Therefore, this vector would have only the following positions:

vetor[0] := 'Olá mundo 1';
vetor[1] := 'Olá mundo 2';
vetor[2] := 'Olá mundo 3';
vetor[3] := 'Olá mundo 4';
vetor[4] := 'Olá mundo 5';

The maximum position is 4, vetor[4]. The smallest is 0, vetor[0], clear-cut.

At first, for those who are learning, this can be a little confusing but get used to the time.

But the dynamic vectors?

As I said, dynamic vectors start without spaces and to work with it you have two conditions:

  1. Know exactly how much space you’ll need;
  2. Add as needed.

In most cases, the dynamic array is used when it is not known how many spaces will be used, and for this it is implemented as necessary.

For this, you need to know some resources to work with arrays in Delphi.

Length function(): Usada para saber o tamanho atual do vetor

var
  vetor: array of string;          
  tamanho: integer;
begin
  tamanho := Length(vetor);  // <-- nesse momento o vetor possui 0 de tamanho, 
                             // ou seja, nenhum espaço para uso

  SetLength(vetor, Length(vetor) + 1);

  tamanho := Length(vetor); // <-- nesse momento o vetor possui 1 de tamanho,
                            // ou seja, 1 espaço para uso, índice 0 (zero) vetor[0].

High function(): Used to know the greatest vector position

var
  vetor: array of string;
  max: integer;
begin
  max := High(vetor); // <-- nesse momento a maior posição do vetor é -1,
                      // ou seja, ainda não há posição, então retorna -1.

  SetLength(vetor, Length(vetor) + 1);

  max := High(vetor); // <-- nesse momento a maior posição do vetor é 0 (zero),
                      // ou seja, o vetor possui uma posição para uso, logo essa 
                      // posição é a 0 (zero)

  SetLength(vetor, Length(vetor) + 1);

  max := High(vetor); // <-- agora, a posição máxima é 1

Setlength function(): Used to set size in dynamic vectors

It was used in the previous examples and I will describe it here:

  1. the first parameter is the vector itself that you want to change its size.
  2. the second parameter is the size you want to set for the vector.

So, to always add an extra position in the vector you use Length() to pick up your current size and then add 1 more.

SetLength(vetor, Length(vetor) - 1);

With the same function you can remove all vector positions

SetLength(vetor, 0);

At last

In your case, I would advise doing the following:

with CreateInArchive(CLSID_CFormat7z) do
begin
  OpenFile('c:\test.7z');
  for i := 0 to NumberOfItems - 1 do
  begin
    if not ItemIsFolder[i] then
    begin
      SetLength(FilesInZ, Length(FilesInZ) + 1);
      FilesInZ[High(FilesInZ)] := ItemPath[i];
    end;
  end;
end;

Note that I add a position: SetLength(FilesInZ, Length(FilesInZ) + 1);

Then I add the value in the last position it has: FilesInZ[High(FilesInZ)] := ItemPath[i];
I used the High() to take the last position.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.