Search only files that match part of the name in a directory

2

I have the following problem

In a certain directory I will need to create files that meet the following criteria.

DOCUMENT_DDMM_SEQ.txt

Where

  • Document : Any number that may or may not be repeated
  • DDMM : Day + Month of the current date
  • SEQ : Directory global directory starting at 001

In order for me to be able to generate the correct sequence, I need to know the value of the last sequence (highest value)

I've been able to get closer reading all the files in the directory to a list and iterating the list in search of the last value, however this method is very bad, since the directory is of the user's choice and it can use a directory that contains many files, making this search very slow. I wanted something that would already filter the files before I had to iterate through the list.

Any suggestions will be evaluated

    
asked by anonymous 28.10.2015 / 19:36

1 answer

1

I was able to do what I wanted by using TSearchRec as follows.

procedure TFrm....
  var search : TSearchRec; // Unit SysUtils
    filename, dirname : String;
    seq, i : Integer;
Begin
  // (...)
  if not SelectDirectory('Selecione o diretório', 'arqs', dirname) then // Unit FileCtrl
    begin
       Application.MessageBox('Sem destino', APPNAME, MB_OK+MB_ICONERROR);
       Exit;
    end;
  try 
    // Pesquisando o diretório corrente para gerar arquivos únicos
    if (FindFirst(dirname + '*_' + FormatDateTime('ddmm', Date) + '_*.txt',
                    faArchive,
                    searchResult) = 0 ) then
      begin
        repeat
          // Extraindo o sequencial do arquivo
          i := LastDelimiter('_', searchResult.Name);
          if (TryStrToInt(copy(searchResult.Name, i, 3), i)) then
            seq := Max(i, seq);
        until FindNext(searchResult) <> 0;
        FindClose(searchResult);
      end;

    filename := NUMERO_DOCUMENTO + '_' +
                FormatDateTime('ddmm', Date) + '_' +
                LPad(IntToStr(seq + 1), 3, '0') + '.txt'; // LPad função privada de padding à esquerda
    // Garantindo que não existe arquivo com a nomenclatura passada
    while FileExists(dirname + filename) do
      begin
        seq := seq + 1;
        filename := NUMERO_DOCUMENTO  + '_' +
                    FormatDateTime('ddmm', Date) + '_' +
                    LPad(IntToStr(seq + 1), 3, '0') + '.txt';

      end;  

    // (Outros códigos ...)
End;
End.

One thing that helped me in this code was the use of TryStrToInt , because it allowed me to prevent a name not ending in _999.txt from causing the application to generate a Exception conversion.

Apparently I could have problems when the sequential arrived in 999 because the next to be generated would be _1000.txt and instead of being able to fetch the value 1000, as I am limiting to 3 characters it will end up taking 100 and iterating in the verification of existence until 1001. It will end up going the wrong way.

One solution would be to find the ".txt" position to calculate the amount of characters to be used for both the copy function and the padding function.

    
29.10.2015 / 22:53