ПОМОГИТЕ.Не знаю и пе понимаю,Как собрать в одну форму все компоненты. Процедура есть,а распределить не могу. Т.е не знаю как будет выглядеть программа после воспроизводства в Delphi.Не разбираюсь. - вопрос №1006140

 

 

 

Программа dupeGuru2.9.0 также позволяет пользователю настраивать алгоритмы сравнения файлов для более точного поиска, например: типы сканирования, жескость фильтра, заданному слову, разброс похожих слов и другие. При поиске программа выводит список найденных файлов с указанием путей, размеров и процентом совпадения.

Основные возможности:

• Быстрый поиск дубликатов, в том числе среди файлов разных форматов;

• настройка программы под конкретные нужды;

• Безопасность — ни один из нужных файлов не будет удален;

• Функция удаления пустых папок;

• Перемещение и копирование дубликатов, удаление плохих копий.

В этой версии исправлены некоторые ошибки:

• Значительно улучшена скорость и использование памяти при сканировании больших массивов.

• Добавлена поддержка drag& dropв панели папок. )

• Исправлена ошибка, приводившая dupeGuruк некорректному отчету при перемещении файлов во время сканирования.

• Прекращена поддержка MacOSX10.4 (Tiger)

 

DupeGuru— небольшая быстрая утилита для поиска дубликатов файлов на компьютере. Интерфейс программы предельно прост: нужно только выбрать область поиска дубликатов (Мои докуметы, все диски, отдельный каталог/типы файлов). Программа просканирует диск и выдаст результат в виде наглядной таблицы. dupeGuruможет просмотреть имена файлов и их содержание. Просмотр имени файла показывает четкий алгоритм соответствия, который может найти двойные имена файла даже когда они не точно похожи.

 

 

Алгоритм:

Производим рекурсивный поиск файлов, по каждому файлу создаем метку = "<имя_файла>:<размер>:<дата>", и сохраняем в бинарное дерево поиска, если такой метки нет, создаем новую, иначе найдены совпадения.

Реализация

Все операции необходимо выполнять в потоке.

type

  TFileSearchThread = class(TThread)

  private

    _TickCountIntervalBeforeRefresh: integer;

    locProgressMax: integer;

    locProgressPosition: integer;

    locSearchFilesDone: integer;

    locCurrentFile: string;

    procedure SetName;

    procedure SetStatus;

    procedure ThreadDone;

    procedure FindFiles(

        paramFolder,

        paramMask: string;

        const paramLevel: integer);

    function GetFilesCount(

        paramFolder: string;

        const paramLevel :integer): integer;

    procedure AddToTree(

        var paramNode: TSearchTreeNode;

        const paramPath: string;

        const paramHash: string;

        const FileSize: integer

        );

  protected

    procedure Execute; override;

  public

    SearchFolder: string;

    Mask: string;

    FilesTree: TSearchTreeNode;

  end;

{$IFDEF MSWINDOWS}

type

  TThreadNameInfo = record

    FType: LongWord;     // must be 0x1000

    FName: PChar;        // pointer to name (in user address space)

    FThreadID: LongWord; // thread ID (-1 indicates caller thread)

    FFlags: LongWord;    // reserved for future use, must be zero

  end;

{$ENDIF}

{ TFileSearchThread }

procedure TFileSearchThread.SetName;

{$IFDEF MSWINDOWS}

var

  ThreadNameInfo: TThreadNameInfo;

{$ENDIF}

begin

{$IFDEF MSWINDOWS}

  ThreadNameInfo.FType := $1000;

  ThreadNameInfo.FName := 'FileSearchThread';

  ThreadNameInfo.FThreadID := $FFFFFFFF;

  ThreadNameInfo.FFlags := 0;

  try

    RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );

  except

  end;

{$ENDIF}

end;

procedure TFileSearchThread.Execute;

begin

  SetName;

  // Calculate less 2 sec

  _TickCountIntervalBeforeRefresh := GetTickCount()+2000;

  locProgressMax := 0;

  locProgressPosition := 0;

  GetFilesCount(SearchFolder, 0);

  // Start search

  _TickCountIntervalBeforeRefresh := 0;

  findfiles(SearchFolder, Mask, 0);

  // finish

  synchronize(ThreadDone);

end;

Рекурсивный поиск файлов

procedure TFileSearchThread.FindFiles(

      paramFolder,

      paramMask: string;

      const paramLevel: integer);

var

  searchrec: tsearchrec;

  findresult: integer;

  hash: string;

begin

  if self.Terminated then

    exit;

  if paramLevel <= uConst.cLevelCountForCalculateFilesCount then

    Inc(locProgressPosition);

  if locProgressPosition > locProgressMax then

    locProgressMax := locProgressPosition;

  // Update status

  if GetTickCount() > _TickCountIntervalBeforeRefresh then

  begin

    //300 — update thread info interval in msec :

    _TickCountIntervalBeforeRefresh := GetTickCount() + 300; //

    locCurrentFile := paramFolder;

    synchronize(SetStatus);

  end;

  paramFolder:=includetrailingbackslash(paramFolder);

  findresult:=findfirst(paramFolder+paramMask, faanyfile, searchrec);

  try

    while findresult = 0 do

    begin

      if (searchrec.attr and fadirectory)<>0 then

      begin

        if (searchrec.name<>'.') and (searchrec.name<>'..') then

          findfiles(paramFolder+searchrec.name, paramMask, paramLevel+1);

      end

      else

      begin

        hash := searchrec.name;

        hash := hash + ':S'+IntToStr(searchrec.Size);

        hash := hash + ':T'+IntToStr(searchrec.Time);

        AddToTree(FilesTree,paramFolder+searchrec.name,hash,searchrec.Size);

      end;

      findresult:=findnext(searchrec);

    end;

  finally

    findclose(searchrec);

  end;

end;

Сохраняем метку файла в бинарное дерево поиска

procedure TFileSearchThread.AddToTree(

        var paramNode: TSearchTreeNode;

        const paramPath: string;

        const paramHash: string;

        const FileSize: integer

        );

begin

  if not Assigned(paramNode) then

  begin

    paramNode := TSearchTreeNode.Create(nil);

    paramNode.Hash := paramHash;

    paramNode.Files := paramPath+'|'+IntToStr(FileSize);

    paramNode.FilesCount := 1;

  end

  else

  begin

    if paramHash > paramNode.Hash then

      AddToTree(paramNode.HiNode,paramPath,paramHash,FileSize)

     else

    if paramHash < paramNode.Hash then

      AddToTree(paramNode.LowNode,paramPath,paramHash,FileSize)

     else

    begin

      paramNode.FilesCount := paramNode.FilesCount + 1;

      paramNode.Files := paramNode.Files + #13#10+ paramPath+'|'+IntToStr(FileSize);

      // count of entry duplicate files

      if paramNode.FilesCount = 2 then

        Inc(locSearchFilesDone);

    end;

  end;

end;

Предварительное определение общего количества файлов

Для удобства UI, а именно для отображения ProgressBar, нам необходимо приблизительно оценить общее количество файлов, для этого мы рекурсивно подсчитываем число каталогов с вложенностью 2-3(задаем параметром в конфигурационном фале).

functionTFileSearchThread.GetFilesCount(

     paramFolder: string;

     const paramLevel :integer): integer;

var

  searchrec: tsearchrec;

  findresult: integer;

  hash: string;

begin

  // Get folder count in hi 5 levels

  if GetTickCount() > _TickCountIntervalBeforeRefresh then

    exit;

  if paramLevel > uConst.cLevelCountForCalculateFilesCount then

    exit;

  if self.Terminated then

    exit;

  Inc(locProgressMax);

    

  paramFolder := includetrailingbackslash(paramFolder);

  findresult:=findfirst(paramFolder+'*.*', faanyfile, searchrec);

  try

    while findresult = 0 do

    begin

      if (searchrec.attr and fadirectory)<>0 then

      begin

        if (searchrec.name<>'.') and (searchrec.name<>'..') then

          GetFilesCount(paramFolder+searchrec.name, paramLevel+1);

      end;

      findresult:=findnext(searchrec);

    end;

  finally

    findclose(searchrec);

  end;

end;

 

 

Ответы

Здравствуйте! Обращайтесь в чат, обсудим решение вашей проблемы

29.03.14

Глеб Черняк

Сейчас на сайте
Читать ответы

Александр

Сейчас на сайте
Читать ответы

Олег Николаевич

Читать ответы
Посмотреть всех экспертов из раздела Технологии
Пользуйтесь нашим приложением Доступно на Google Play Загрузите в App Store