Fórum Problema com Threads... #397112
11/03/2011
0
procedure MinhaThread.Execute;
begin
Fileslist := TStringList.Create;
LComparar := TStringList.Create;
synchronize(copiar);
FindFiles(FilesList, 'c:', '*.*', True);
{ Place thread code here }
end;
procedure MinhaThread.FindFiles(FilesList: TStringList; StartDir, Mascara: string; IncludeRoot: boolean);
begin
if length(StartDir) <> 0 then
begin
if StartDir[length(StartDir)] <> '\' then
begin
StartDir := StartDir + '\';
end;
for l := 0 to LComparar.Count - 1 do
begin
Mascara := LComparar[l];
IsFound := FindFirst(StartDir + Mascara, faAnyFile - faDirectory, SR) = 0;
while IsFound do
begin
FilesList.Add(StartDir + SR.Name);
synchronize(AtualizaResult);
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
end;
if IncludeRoot = true then
// Cria lista de subdirectorios
IsFound := FindFirst(StartDir + '*.*', faAnyFile, SR) = 0;
while IsFound do
begin
ListaDir := TStringList.Create;
if ((SR.Attr and faDirectory) <> 0) and (SR.Name[1] <> '.') and (SR.Name <> 'Windows') then
begin
ListaDir.Add(StartDir + SR.Name);
// synchronize(AtualizaBusca);
IsFound := FindNext(SR) = 0;
end;
end;
FindClose(SR);
// Procura dentro da lista
for i := 0 to ListaDir.Count - 1 do
startdir:=listadir[i];
FindFiles(FilesList, ListaDir[i], Mascara, IncludeRoot);
ListaDir.free;
end;
end;
procedure MinhaThread.copiar;
begin
LComparar.Assign(form5.LComparar.Items);
end;
procedure MinhaThread.AtualizaBusca;
begin
form5.LProcurando.Items.Assign(ListaDir);
end;
procedure MinhaThread.AtualizaResult;
begin
form5.LEncontrado.Items.Assign(FilesList);
end;
Até a parte do includeroote=true o codigo funciona, o problema esta no looping para procurar em subdiretorios eu acho, pois se eu executo FindFiles(..,..,..,False) ele transcorre bem, e procura os arquivos numa boa, mas quando é pra começar a procurar em subdiretorios, que foi aquele looping que eu criei com StringList ele da erro, o erro é na hora da utilizaçao, o erro que persiste agora é o "Out Of Memory"..
Como soluciono.
Guilherme Marini
Curtir tópico
+ 0Posts
11/03/2011
Marco Salles
Gostei + 0
11/03/2011
Guilherme Marini
interface
uses
Classes, Sysutils;
type
MinhaThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure FindFiles(FilesList: TStringList; StartDir, Mascara: string;
IncludeRoot: boolean);
procedure AtualizaBusca;
procedure AtualizaResult;
procedure copiar;
end;
var
startdir, mascara: string;
includeroot : boolean;
ListaDir, LComparar, FilesList: TStringList;
SR: TSearchRec;
IsFound: boolean;
i, l: integer;
implementation
uses unit5;
procedure MinhaThread.Execute;
begin
Fileslist := TStringList.Create;
LComparar := TStringList.Create;
synchronize(copiar);
FindFiles(FilesList, 'c:', '*.*', True);
{ Place thread code here }
end;
procedure MinhaThread.FindFiles(FilesList: TStringList; StartDir, Mascara: string; IncludeRoot: boolean);
begin
if length(StartDir) <> 0 then
begin
if StartDir[length(StartDir)] <> '\' then
begin
StartDir := StartDir + '\';
end;
for l := 0 to LComparar.Count - 1 do
begin
Mascara := LComparar[l];
IsFound := FindFirst(StartDir + Mascara, faAnyFile - faDirectory, SR) = 0;
while IsFound do
begin
FilesList.Add(StartDir + SR.Name);
synchronize(AtualizaResult);
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
end;
if IncludeRoot = true then
// Cria lista de subdirectorios
IsFound := FindFirst(StartDir + '*.*', faAnyFile, SR) = 0;
while IsFound do
begin
ListaDir := TStringList.Create;
if ((SR.Attr and faDirectory) <> 0) and (SR.Name[1] <> '.') and (SR.Name <> 'Windows') then
begin
ListaDir.Add(StartDir + SR.Name);
// synchronize(AtualizaBusca);
IsFound := FindNext(SR) = 0;
end;
end;
FindClose(SR);
// Procura dentro da lista
for i := 0 to ListaDir.Count - 1 do
startdir:=listadir[i];
FindFiles(FilesList, ListaDir[i], Mascara, IncludeRoot);
ListaDir.free;
end;
end;
procedure MinhaThread.copiar;
begin
LComparar.Assign(form5.LComparar.Items);
end;
procedure MinhaThread.AtualizaBusca;
begin
form5.LProcurando.Items.Assign(ListaDir);
end;
procedure MinhaThread.AtualizaResult;
begin
form5.LEncontrado.Items.Assign(FilesList);
end;
end.
essa eh a unit da thread, desconsidere esse LProcurando, eh apenas um tlistbox que vai listando as pastas procuradas, mas note que eu nao estou usando ela ainda, o LComparar eh uma Tlist box da unit principal que tem os filtros da busca, e o LEncontrado eh um TListbox onde vai ser inserido o resultado da busca.
estou chamando a thread assim:
procedure TForm5.BProcurarClick(Sender: TObject);
var FilesList : TStringList;
begin
Teste := MinhaThread.Create(true);
Teste.FreeOnTerminate := true;
Teste.Priority := tpNormal;
Teste.Resume;
end;
onde esta o erro, como eu ja disse, a thread eh executada numa boa se eu deixo o Includeroot como false, ou seja o problema esta no looping pra listar e procurar nas subpastas!
Gostei + 0
11/03/2011
Marco Salles
begin
ListaDir := TStringList.Create; por isto o erro de Out Of Memory .. Fica instanciando essas listas ... Realmente a THread é indicado para destravar a aplicação , ja que o calculoo é feito em segundo Plano seria melhor talves ( ao ter que conserar o seu cógido que para mim apresenta problema ) e fazer utilizando outra lógica . O que vc pretende listar no ListBox qnd vc cria esta THread ??? ps) eu disse me parece ... .. para finalizar so dois adendos 1) Vc conhece o DirectoryListBox ???? Nativo do Delphi 2)Unidade IOutils.pas … Similar ao NomeSpace System.IO presente no .NET Possui Classes que facilita o Trabalho com Arquivos e Diretórios TDirectory TPath TFile
Gostei + 0
11/03/2011
Guilherme Marini
eu consegui fazer atraves desse processo citado acima com que ele busque os arquivos em c:, e com sucesso, ele acha todos os arquivos que mandei procurar.
mas eu estou com problema na hora de procurar esses arquivos nos sub-diretorios
eu estou fazendo o seguinte esquema, usando a procedure FindFiles(FileList,StartDir,Mascara,includeroot)
ou seja FindFiles('Liststring para salvar resultados da busca','Diretorio de onde começar a busca','tipo d arquivos que procurar(nao interfere pois eu mudo dentro do procedure','Incluir subdiretorios')
Na minha cabeça o programa deveria agir assim:
1º Ele faz a busca em c:, que é o primeiro diretorio a ser procurado, e salva se achar algum arquivo na stringlist(FileList).
2º Ele procura agora pelas pastas dentro de c: e salva na stringlist(ListaDir)
3º Ele pega cada string da stringlist(ListDir), usa como StartDir e executa a procedure FindFiles denovo.
desse jeitu ele criaria um looping no qual ele continuaria a procurar dentro de um diretorio ate nao haver mais pasta, dae ele volta la no começo e pega a segunda string da string list e faz o mesmo processo, ate ele ter procurado em todas as pastas.
olhe, achei um jeitu em que ele nao da erro out of memory, maaaass ele tambem nao procura tudo, stacka em algum lugar.
unit Unit7;
interface
uses
Classes, Sysutils;
type
MinhaThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure FindFiles(FilesList: TStringList; StartDir, Mascara: string;
IncludeRoot: boolean);
procedure AtualizaBusca;
procedure AtualizaResult;
procedure copiar;
end;
var
startdir, mascara: string;
includeroot : boolean;
ListaDir, LComparar, FilesList: TStringList;
SR: TSearchRec;
IsFound: boolean;
i, l: integer;
implementation
uses unit5;
procedure MinhaThread.Execute;
begin
Fileslist := TStringList.Create;
LComparar := TStringList.Create;
synchronize(copiar);
FindFiles(FilesList, 'c:', '*.*', True);
{ Place thread code here }
end;
procedure MinhaThread.FindFiles(FilesList: TStringList; StartDir, Mascara: string; IncludeRoot: boolean);
begin
if length(StartDir) <> 0 then
if StartDir[length(StartDir)] <> '\' then
begin
StartDir := StartDir + '\';
end;
for l := 0 to LComparar.Count - 1 do
begin
Mascara := LComparar[l];
IsFound := FindFirst(StartDir + Mascara, faAnyFile - faDirectory, SR) = 0;
while IsFound do begin
FilesList.Add(StartDir + SR.Name);
synchronize(AtualizaResult);
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
end;
if IncludeRoot = true then
begin
// Cria lista de subdirectorio
ListaDir := TStringList.Create;
IsFound := FindFirst(StartDir + '*.*', faAnyFile, SR) = 0;
while IsFound do begin
if ((SR.Attr and faDirectory) <> 0) and (SR.Name[1] <> '.') and (SR.Name <> 'Windows') then
begin
ListaDir.Add(StartDir + SR.Name);
// synchronize(AtualizaBusca);
IsFound := FindNext(SR) = 0;
end;
end;
FindClose(SR);
// Procura dentro da lista
for i := 0 to ListaDir.Count - 1 do
FindFiles(FilesList, ListaDir[i], Mascara, IncludeRoot);
ListaDir.free;
end;
end;
procedure MinhaThread.copiar;
begin
LComparar.Assign(form5.LComparar.Items);
end;
procedure MinhaThread.AtualizaBusca;
begin
form5.LProcurando.Items.Assign(ListaDir);
end;
procedure MinhaThread.AtualizaResult;
begin
form5.LEncontrado.Items.Assign(FilesList);
end;
end.
cara se voce souber algum jeitu de eu procurar arquivos com com base em uma lista de nomes e extensoes, que procure em sub-diretorios tambem, por favor me diga, passe uma unit pronta se possivel.
Gostei + 0
11/03/2011
Marco Salles
Gostei + 0
11/03/2011
Guilherme Marini
Gostei + 0
11/03/2011
Marco Salles
var
path:string;
i:integer;
begin
if not TDirectory.Exists(edtDirectory.text) then
Caption := 'Invalid Path'
else
Caption := DirectoryListBox1.Directory;
ListBox1.Clear;
for path in TDirectory.GetFiles(edtDirectory.text,
edtFilter.Text,
TSearchOption.soAllDirectories) do
ListBox1.Items.Add(Format('Name = %s', [Path]));Gostei + 0
12/03/2011
Guilherme Marini
Gostei + 0
12/03/2011
Marco Salles
Gostei + 0
12/03/2011
Guilherme Marini
tem alguma ideia de como fazer?
Gostei + 0
12/03/2011
Guilherme Marini
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, unit7;
type
TForm5 = class(TForm)
BProcurar: TButton;
LEncontrado: TListBox;
LProcurando: TListBox;
LComparar: TListBox;
ListaDir: TListBox;
procedure BProcurarClick(Sender: TObject);
private
procedure FindFiles(FilesList: TStringList; StartDir, Mascara: string; IncludeRoot:boolean);
{ Private declarations }
public
{ Public declarations }
end;
var
Form5: TForm5;
teste: MinhaThread;
implementation
{$R *.dfm}
procedure TForm5.BProcurarClick(Sender: TObject);
var FilesList : TStringList;
begin
FilesList := TStringList.Create;
findfiles(FilesList,'c:','*.*',true);
LEncontrado.Items.Assign(Fileslist);
end;
procedure TForm5.FindFiles(FilesList: TStringList; StartDir, Mascara: string; IncludeRoot:boolean);
var
SR: TSearchRec;
ListaDir: TStringList;
IsFound: Boolean;
i,l: integer;
begin
if length(StartDir)<>0 then
if StartDir[length(StartDir)] <> '\' then
begin
StartDir := StartDir + '\';
end;
for l:=0 to LComparar.Count-1 do
begin
Mascara:=LComparar.Items[l];
IsFound :=FindFirst(StartDir+Mascara, faAnyFile-faDirectory, SR) = 0;
while IsFound do begin
FilesList.Add(StartDir + SR.Name);
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
end;
if IncludeRoot=true then
begin
// Cria lista de subdirectorios
ListaDir := TStringList.Create;
IsFound := FindFirst(StartDir+'*.*', faAnyFile, SR) = 0;
while IsFound do begin
if ((SR.Attr and faDirectory)<>0) and
(SR.Name[1] <> '.') and (SR.Name <> 'Windows') then
ListaDir.Add(StartDir + SR.Name);
LProcurando.Items.Assign(ListaDir);
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
// Procura dentro da lista
for i := 0 to ListaDir.Count - 1 do
FindFiles(FilesList, ListaDir[i], Mascara,includeroot);
ListaDir.Free;
end;
end;
end.
Da pra por na thread?
Gostei + 0
13/03/2011
Guilherme Marini
Gostei + 0
19/03/2011
Guilherme Marini
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)