Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-03-2013
Avatar de Julián
Julián Julián is offline
Merodeador
 
Registrado: may 2003
Ubicación: en mi casa
Posts: 2.029
Poder: 10
Julián Va por buen camino
Para eso lo mejor puede ser usar el api de windows, que permite colgar un hook o como se llame que "avisa" cada vez que se modifique el archivo que quieras. No me acuerdo que función es, pero existe.


EDITO: Una busqueda en google por "delphi file notification" devielve un motón de entradas parecidas a esta: http://www.delphi-central.com/compon...ification.aspx
__________________
"la única iglesia que ilumina es la que arde"
Anonimo
Responder Con Cita
  #2  
Antiguo 24-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Gracias Julian, lo estudiaré :-)
Saludos.
Responder Con Cita
  #3  
Antiguo 24-03-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 23
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
paquechu,

Cita:
Empezado por paquechu
...no se el tamaño maximo (no de lineas) sino de memoria que se puede cargar con un tstringlist...
Un String en Delphi 7 (AnsiString, WideString) tiene un tamaño máximo de 2 GB, revisa este link: Limitation of TStringList.

Cita:
Empezado por paquechu
...me preocupa el tiempo de carga y el consumo excesivo de memoria...
EL código propuesto debería funcionar correctamente en archivos de texto que no sean de un tamaño notable (Logs rotativos), el ejemplo mencionado de 2.000.000 de lineas de texto fue solo a efectos de prueba de la función.

Te sugiero revisar detalladamente el código del Msg #6 (function GetLastLine), el código es altamente eficiente dado que solo obtiene la última línea del archivo de forma directa, lo cual la hace ideal como parte de un control TTimer y sin sobrecarga de recursos. Como comentario, funciono de forma optima con el archivo de pruebas mencionado.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 24-03-2013 a las 23:04:51.
Responder Con Cita
  #4  
Antiguo 25-03-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola paquechu.

Dado que la aplicación que genera el log añade líneas, este cambiará su tamaño. Entonces, una forma de detectar si se agregó una linea usando un TTimer, podría ser:
Código Delphi [-]
  ...
  private
    FPreviousSize: Int64; // Ultimo tamaño monitoreado   
  end;

...

implementation

const
   NOMARCH = 'C:\LOG.TXT'; // Ruta hasta y nombre del archivo

(* Obtener tamaño del archivo *)
function FileLongSize(const aFileName: string): Int64;
var
  FindData: TWin32FindData;
begin
  Windows.FindClose(FindFirstFile(PChar(aFileName), FindData));
  Result := FindData.nFileSizeHigh shl 32 + FindData.nFileSizeLow;
end;

(* Obtener última línea *)
function GetLastLine(const aFileName: string): string;
var
  FS  : TFileStream;
  buf : Char;
  i   : Integer;
begin
  FS := TFileStream.Create(aFileName, fmOpenRead);
  try
    Result := '';
    i := FS.Size + 2;
    repeat
      FS.Seek(FS.Size-i, soEnd);
      FS.Read(buf, SizeOf(buf));
      Insert(buf, Result, 1);
      Inc(i);
    until (buf = #10);
  finally
    FS.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Tamaño al inicio del monitoreo
  FPreviousSize:= FileLongSize(NOMARCH); 
  //Timer1.Interval := ??? (a tu necesidad)
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  NewSize: Int64;
begin
  NewSize:= FileLongSize(NOMARCH);  // Nuevo tamaño
  if FPreviousSize <>  NewSize then 
  begin
    FPreviousSize:= NewSize;
    Timer1.Enabled:= False;
    // Aca lo que gustes hacer con la última línea, para el ejemplo la muestro.
    MessageBox(Handle,PChar(GetLastLine(NOMARCH)),'NUEVA LINEA',MB_ICONEXCLAMATION);
    Timer1.Enabled:= True;
  end;
end;
...
No sé si es la forma mas optima, pero es simple y en mis pruebas funciona. Hasta que encuentres algo mejor tal vez te sirva...

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 25-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Hola Ecfisa,
COmo comentaba en mi anterior mensaje, el código que he utilizado se basa en tu funcion GetLastLine.
Ya veo que lo has mejorado.
Lo voy a probar (aunque la adaptación que os puse también me funciona).
Un saludo y gracias.

Cita:
Empezado por ecfisa Ver Mensaje
Hola paquechu.

Dado que la aplicación que genera el log añade líneas, este cambiará su tamaño. Entonces, una forma de detectar si se agregó una linea usando un TTimer, podría ser:

Código Delphi [-]
...
private
FPreviousSize: Int64; // Ultimo tamaño monitoreado
end;

...

implementation

const
NOMARCH = 'C:\LOG.TXT'; // Ruta hasta y nombre del archivo

(* Obtener tamaño del archivo *)
function FileLongSize(const aFileName: string): Int64;
var
FindData: TWin32FindData;
begin
Windows.FindClose(FindFirstFile(PChar(aFileName), FindData));
Result := FindData.nFileSizeHigh shl 32 + FindData.nFileSizeLow;
end;

(* Obtener última línea *)
function GetLastLine(const aFileName: string): string;
var
FS : TFileStream;
buf : Char;
i : Integer;
begin
FS := TFileStream.Create(aFileName, fmOpenRead);
try
Result := '';
i := FS.Size + 2;
repeat
FS.Seek(FS.Size-i, soEnd);
FS.Read(buf, SizeOf(buf));
Insert(buf, Result, 1);
Inc(i);
until (buf = #10);
finally
FS.Free;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// Tamaño al inicio del monitoreo
FPreviousSize:= FileLongSize(NOMARCH);
//Timer1.Interval := ??? (a tu necesidad)
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
NewSize: Int64;
begin
NewSize:= FileLongSize(NOMARCH); // Nuevo tamaño
if FPreviousSize <> NewSize then
begin
FPreviousSize:= NewSize;
Timer1.Enabled:= False;
// Aca lo que gustes hacer con la última línea, para el ejemplo la muestro.
MessageBox(Handle,PChar(GetLastLine(NOMARCH)),'NUEVA LINEA',MB_ICONEXCLAMATION);
Timer1.Enabled:= True;
end;
end;
...




No sé si es la forma mas optima, pero es simple y en mis pruebas funciona. Hasta que encuentres algo mejor tal vez te sirva...

Saludos.
Responder Con Cita
  #6  
Antiguo 25-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Por mi parte, me doy más que satisfecho con la acogida y ayuda que me habeis prestado y doy por cerrado este asunto.
Estaba un poco agobiadete con este tema.
Muchisimas gracias a todos
Un cordial saludo
Responder Con Cita
  #7  
Antiguo 25-03-2013
Avatar de Julián
Julián Julián is offline
Merodeador
 
Registrado: may 2003
Ubicación: en mi casa
Posts: 2.029
Poder: 10
Julián Va por buen camino
Lo mas optimo se supone que sería usar el gestlastline que estais comentando, pero en lugar de con un ttimer, con el evento del api de windows (el que te comenté en mi mensaje anterior) que se lanza sólo cuando se modifica el fichero.

Un saludo!
__________________
"la única iglesia que ilumina es la que arde"
Anonimo
Responder Con Cita
  #8  
Antiguo 25-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Hola Julian, coincido contigo totalmente.
Solo me queda una duda, que es donde falla el procedimiento que he adaptado basado en la funcion getlastline, y es la forma en la que se está generando el archivo de log.

Si al generar las líneas del archivo de log se hace un flush por cada línea generada, funciona OK, pero si el flush se hace cada ciertas líneas entonces no funciona bien. No se si este componente contemplaria este caso...

Saludos.

Cita:
Empezado por Julián Ver Mensaje
Lo mas optimo se supone que sería usar el gestlastline que estais comentando, pero en lugar de con un ttimer, con el evento del api de windows (el que te comenté en mi mensaje anterior) que se lanza sólo cuando se modifica el fichero.

Un saludo!
Responder Con Cita
  #9  
Antiguo 25-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Hola nlsgarcia,
Gracias por las aclaraciones, respecto al codigo del mensaje numero 6 (GetLastLine), efectívamente, es el que he tomado como base y he logrado adaptar a la idea que iba buscando.
Muchas gracias :-)

Cita:
Empezado por nlsgarcia Ver Mensaje
paquechu,


Un String en Delphi 7 (AnsiString, WideString) tiene un tamaño máximo de 2 GB, revisa este link: Limitation of TStringList.


EL código propuesto debería funcionar correctamente en archivos de texto que no sean de un tamaño notable (Logs rotativos), el ejemplo mencionado de 2.000.000 de lineas de texto fue solo a efectos de prueba de la función.

Te sugiero revisar detalladamente el código del Msg #6 (function GetLastLine), el código es altamente eficiente dado que solo obtiene la última línea del archivo de forma directa, lo cual la hace ideal como parte de un control TTimer y sin sobrecarga de recursos. Como comentario, funciono de forma optima con el archivo de pruebas mencionado.

Espero sea útil

Nelson.
Responder Con Cita
  #10  
Antiguo 26-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Buenas,

He probado el código que proponias, sin embargo al ejecutarlo sobre un archivo abierto de log se "queja" de que está abierto por otra aplicación y no puede continuar..... seguiré probando el resto de vuestras propuestas :-)
Saludos.

Cita:
Empezado por nlsgarcia Ver Mensaje
paquechu,


Un String en Delphi 7 (AnsiString, WideString) tiene un tamaño máximo de 2 GB, revisa este link: Limitation of TStringList.


EL código propuesto debería funcionar correctamente en archivos de texto que no sean de un tamaño notable (Logs rotativos), el ejemplo mencionado de 2.000.000 de lineas de texto fue solo a efectos de prueba de la función.

Te sugiero revisar detalladamente el código del Msg #6 (function GetLastLine), el código es altamente eficiente dado que solo obtiene la última línea del archivo de forma directa, lo cual la hace ideal como parte de un control TTimer y sin sobrecarga de recursos. Como comentario, funciono de forma optima con el archivo de pruebas mencionado.

Espero sea útil

Nelson.
Responder Con Cita
  #11  
Antiguo 26-03-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por paquechu Ver Mensaje
Buenas,

He probado el código que proponias, sin embargo al ejecutarlo sobre un archivo abierto de log se "queja" de que está abierto por otra aplicación y no puede continuar
Hola paquechu.

Muy probablemente tengas ese problema con cualquiera de las sugerencias de este hilo, eso es a lo que me refería en el mensaje (#4).

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #12  
Antiguo 26-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Si, eso es, pero se soluciona añadiendo el flag fmShareDenyNone en el momento de abrir el archivo
Saludos. :-)

Cita:
Empezado por ecfisa Ver Mensaje
Hola paquechu.

Muy probablemente tengas ese problema con cualquiera de las sugerencias de este hilo, eso es a lo que me refería en el mensaje (#4).

Saludos.
Responder Con Cita
  #13  
Antiguo 26-03-2013
paquechu paquechu is offline
Miembro
 
Registrado: oct 2008
Posts: 51
Poder: 18
paquechu Va por buen camino
Ecfisa,
Por otro lado he probado el codigo que pones en el mensaje #17, pero tampoco contempla todas las líneas añadidas desde la última modificación y se "traga" algunas... sigo pensando que es lo del flush, je,je
Gracias :-)

EDITO: Otra cosa mas.... he intentado descargarme el ejemplo del mensaje #26 y no puedo, no se si será por el control de contenido de mi trabajo, pero al abrir el zip se queja de error crc (lo he intentado varias veces. lo probaré desde casa)....

Última edición por paquechu fecha: 26-03-2013 a las 12:52:29.
Responder Con Cita
  #14  
Antiguo 26-03-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por paquechu Ver Mensaje
Ecfisa,
Por otro lado he probado el codigo que pones en el mensaje #17, pero tampoco contempla todas las líneas añadidas desde la última modificación y se "traga" algunas... sigo pensando que es lo del flush, je,je
Gracias :-)
Es que el código que te sugerí no hace eso. El código devuelve la ultima línea añadida, no el conjunto de líneas agregadas desde desde la última modificacion.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #15  
Antiguo 26-03-2013
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por paquechu Ver Mensaje
Si, eso es, pero se soluciona añadiendo el flag fmShareDenyNone en el momento de abrir el archivo
Saludos. :-)
Si, es correcto, pero te lo señalaba por el comentario de tu mensaje anterior (#28).

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 22:13:56.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi