Fórum Contagem de Linha (arquivo TXT) #182506
17/09/2003
0
No caso é um arquivo log do sistema... e quero inserir o número de cada registro, ou seja, inserir o numero 1 na primeira linha e ir incrementando a cada registro.
Uso o codigo abaixo para inserir as linhas...
--------------------------------------------
procedure RegistraLog (msg:string);
var f : textfile;
sr : TSearchRec;
begin
AssignFile (f, ´arquivo.log´);
if FindFirst (´arquivo.log´, faAnyFile, sr) = 0 then
begin
{$I-}
Reset (f);
{$I+}
IOResult;
end else
ReWrite (f);
Append (f);
WriteLn (f, DateTimeToStr (now), ´ ´, msg); // coloca a data e hora atual com a mensagem do registro na frente.
CloseFile (f);
end;
-----------------------------------------------------
Então preciso de um jeito para saber qual o número de linhas do arquivo para incrementar esse valor e colocar na proxima linha.
Agradeço a atenção,
Renato Mendes
Renato_mendes
Curtir tópico
+ 0Posts
17/09/2003
Bacalhau
procedure RegistraLog (msg:string);
var f : textfile;
sr : TSearchRec;
i : integer; // adicionei esta variável
begin
i := 0; // inicializo
AssignFile (f, ´arquivo.log´);
Reset (f);
while not eof(f) do
begin
readln(f);
i := i + 1; // conto aqui o numero de linhas
end;
i := i + 1; // incremento o total de linhas lidas
closefile(f);
Append (f);
WriteLn (f, inttostr(i),DateTimeToStr (now), ´ ´, msg); // coloca valor de i
CloseFile (f);
end;
Abraço
bacalhau
Gostei + 0
18/09/2003
Renato_mendes
Havia pensado em fazer uma rotina desse tipo para a contagem de linhas... só que achei que o pocessamento poderia ficar meio pesado, sendo que o arquivo vai crescendo e pode conter milhares de linhas... além de que em certos horários essa função pode ser executada várias vezes por segundo.
De qq jeito vou usar a tua ideia e ver como o sistema se comporta!!
Abraço,
Renato Mendes
Gostei + 0
18/09/2003
Wbb
Insira no form um controle Memo e faça o seguinte:
Memo1.Lines.LoadFromFile(´C:\Temp\Arquivo.Log´); Edit1.Text := IntToStr(Memo1.Lines.Count);
Eu tentei criar uma variável do tipo TMemo, apenas para não ter que colocar o Memo no form e deixá-lo invisível, porém dá um erro que não sei resolver. Caso você tente criar a variável também e resolva o erro, me diga como.
Ok?
Até mais.
wbb
Gostei + 0
18/09/2003
Bacalhau
O wbb parece ter uma solução mais elegante. Se ele disser qual é o erro, talvez se possa dar uma solução diferente. Wbb, qual é o erro?
Gostei + 0
19/09/2003
Wbb
Só lembrando que o problema acontece apenas quando eu tento executar o programa utilizando de uma variável do tipo TMemo. Quando eu coloco um controle Memo fisicamente no Form, não dá problema algum.
1º) Criei uma variável do tipo TMemo: [b:1c7a991ed8]Var Arquivo: TMemo;[/b:1c7a991ed8];
2º) Criei um arquivo texto contendo 8 linhas em: [b:1c7a991ed8]C:\Temp\testeA.txt[/b:1c7a991ed8];
3º) Criei o código no evento OnClick de um Button:
procedure TForm1.Button1Click(Sender: TObject); Var Arquivo: TMemo; begin Arquivo.Lines.LoadFromFile(´C:\Temp\testeA.txt´); Edit1.Text := IntToStr(Arquivo.Lines.Count); end;
4º) Rodando o programa e clicando no botão, aparece imediatamente, logo na primeira linha, a seguinte mensagem:
[b:1c7a991ed8]Project Project1.exe raised exception class EAccessViolation with message ´Access violation at address 0044F04E in module ´Project1.exe´. Read of address 84FFFDAF´. Process stopped. Use Step or Run to continue.[/b:1c7a991ed8]
Não faço a menor idéia do que seja...
Dê uma forcinha aí Bacalhau! É certo que funciona do jeito que expliquei antes (com um Memo), mas nada melhor do que fazer as coisas certinhas...
Até mais.
wbb
Gostei + 0
19/09/2003
Ljr
Pensando em otimizacao, usei este codigo e da certo. Pois vc usa somente a propriedade LINES, entao usei uma variavel do mesmo tipo, portanto ficara mais leve.
var
f: TStringList;
begin
f:= TStringList.Create;
f.LoadFromFile(´C:\Temp\testeA.txt´);
Edit1.Text := IntToStr(f.Count);
end;
Espero ter ajudado
Gostei + 0
19/09/2003
Wbb
Eu havia tentado usar um TStringList também, mas o mesmo erro ocorria. Agora, resolvido então.
Valeu!
wbb
Gostei + 0
19/09/2003
Ljr
Se vc quiser usar uma variavel do TMemo, use o codigo a seguir:
var
f: TMemo;
begin
f:= TMemo.Create(Self);
f.Visible:= False;
f.Parent:= Form1;
f.Lines.LoadFromFile(´c:\windows\desktop\ss.txt´);
caption:= IntToStr(f.Lines.Count);
f.Free;
end;
Note que eu Atribui False para a propriedade VISIBLE, caso feito o contrario vc podera visualisar o componente no formulario.
Usei o metodo FREE, para retira-lo da memoria.
espero ter ajudado
Gostei + 0
19/09/2003
Bacalhau
procedure TForm1.NumeroDeLinhas(Sender: TObject);
var arquivo : TMemo;
linhas : integer;
begin
arquivo := TMemo.create(arquivo);
arquivo.Parent := form1;
Arquivo.Lines.LoadFromFile(´teste.txt´);
linhas := Arquivo.Lines.Count;
arquivo.free;
end;
Gostei + 0
19/09/2003
Marcelo Saviski
vamos ajeitar isso:
se você quer retornar quantas linhas tem no arquivo, provavelmente a 1º função que o bacalhau passou vai ser mas rápida do que ficar usando um Memo, que foi projetado para outra coisa
essa função abaixo, foi retiradas das 800 dicas da LhoydSoft
function NumLinhasArq(Arqtexto:String): integer; // Retorna o número de linhas que um arquivo possui Var f: Textfile; linha, cont:integer; Begin linha := 0; cont := 0; AssignFile(f,Arqtexto); Reset(f); While not eof(f) Do begin ReadLn(f); Cont := Cont + 1; end; Closefile(f); result := cont; end;
mas se por algum motivo vc´s não quiserem usar ela,
ou quiserem usar TStrings, façam assim:
var Arquivo : TStrings; begin Arquivo := TStringList.Create(self); //Instancia o objeto try Arquivo.LoadFromFile(´ArquivoTal.log´); Quantidade_de_Linhas := Arquivo.Count; finally //Garante que o objeto vai ser liberado Arquivo.Free; end; end;
e vc também não presisa ficar chamando ela várias vezes por segundo, crie uma variável para receber o resultado da função, assim, toda vez que presisar saber o nº de linhas do arquivo, pega o valor da variável,
e toda vez que alterar o arquivo, repita a operação
Gostei + 0
19/09/2003
Wbb
E, para o Marcelo Saviski, uma curiosidade minha: Como faço para que a rotina da [i:6781c6d73c][b:6781c6d73c]function NumLinhasArq(Arqtexto:String): integer;[/b:6781c6d73c][/i:6781c6d73c] que você indicou, seja mais rápida para determinar o número de linhas do arquivo, do que da forma com TStringList? Pergunto isso, pois fiz testes com arquivos grandes, sendo apresentada mais rápida a resposta com TStringList.
Grato!
wbb
Gostei + 0
19/09/2003
Marcelo Saviski
não fiz nenhum teste para saber ao certo, mas se com StringList é mais Agil, vamos de StringList então 8)
e sobre o Arquivo.Free;
em todas as funções que eu vi, é feito assim.
acho que Arquivo não é liberada ao final da Rotina.
e assim fica mais seguro
estou sem o Delphi para poder testar, mas se vc puder, tenta isso:
function ObjetoDestruidoAoFimDaRotina : boolean; var s : TStrings; begin if not Assign(s) then begin s := TStringLis.Create(self); result := true; end else Result := false; end;
e chame assim, em algum Button:
ObjetoDestruidoAoFimDaRotina;// chama ela 1 vez para que crie o Objeto if ObjetoDestruidoAoFimDaRotina then ShowMessage(´O Objeto não foi destruido na última vez que a função foi chamada´);
é só um teste para tirar essa dúvida
Pelo o que eu sabia, era que Strings, Arrays, Variants,... são Liberados automaticamente, quanto aos outros, não sei
se vc puder, faça o teste e diga o que aconteceu
vlw
Gostei + 0
20/09/2003
Bacalhau
O que fiz foi:
criei o TMemo (create)
executei o que queria
libertei o TMemo da memória (free). pq já não preciso dele
Para o caso de queremos aceder várias vezes por segundo, o melhor é criar o TMemo como variavel global, fazer o Create na propriedade FormCreate e destruí-lo em OnClose.
E já que estamos numa de enriquecer este tópico :lol: sugiro fazermos um teste.
Criamos duas variáveis Time_ini e Time_fim do tipo TDateTime. Antes de iniciar a operação capturamos a hora que começou e no fim capturamos a hora que terminou. Isto determina o tempo gasto na operação.
Depois criamos um txt com 10000 linhas (ou mais...) e executamos a minha rotina inicial, depois com o TMemo e depois com o StringList.
A que der um tempo mais baixo é declarada vencedora e o Renato vai usá-la :lol:
Abraço com as barbatanas do peixão norueguês
Gostei + 0
20/09/2003
Mandachuva
OLha, isso que eu chamo de enjambração, ou melhor, gambiarra. Usar TMemo pra contar linhas de arquivos? Se por um lado, a contagem de linhas via WHILE NOT EOF()..READLN() é lenta, por outro lado, via TMemo, não há dierença alguma, pois o mesmo terá que carregar todo o arquivo na memória. E se o arquivo for gigante? Haja memória hein!
Usando TStringList ou usando as funções ´puras´ do pascal seria a forma mais profissional de fazer isso.
Tchau.
Gostei + 0
20/09/2003
Wbb
Apelou heim Bacalhau!!! hahahahahahahaha......
Acho que Renato já até resolveu o problema dele e nós estamos aqui ainda... Também, nada melhor do fazermos o que gostamos e ainda dar umas risadas...
Até mais!
:lol:
wbb
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)