Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Question Búsqueda de archivos ordenada por fecha

Hola compañeros, espero que no hayan tenido mucha bronca por lo de las cervezas que les pasé... les juro que no tenían virus AH1N1 ni HSBC ni CTVS ni nada por el estilo .

Vamos a la duda... tengo una aplicación que lee un directorio con archivos de datos generados por otra aplicación y los procesa, no tenía problema pues eran pocos los archivos así que podía darme el lujo de leer todos los nombres de archivos con su fecha y hora de creación y después ordenarlos para seleccionar los más antiguos y procesarlos de los más antiguos a los más recientes, pero han hecho cambios a la forma en que trabaja el programa que genera los archivos de datos y ahora crea muchísimos archivos de datos que deben ser procesados en el menor tiempo posible, pero mi código tarda muchísimo en leer el directorio completo y después ordenar los nombres de archivo por su fecha de creación, ¿qué me sugieren hacer?

En un principio hacía esto:

Leía los nombres de todos los archivos y su fecha de creación con FindFirst y Findnext, guardándolos en una lista, windows devuelve los nombres de los archivos ordenados alfabéticamente, por lo que debo hacer un proceso para ordenar esta lista por fecha de la menor a la mayor, este proceso es muy rápido si los archivos que hay en el directorio son 100, 200 o incluso 1,000, pero ahora los archivos llegan a ser más de 70,000, incluso ayer eran casi el doble 130,000, por lo que el proceso que les describí anteriormente es muy tardado, he pensado si hay alguna función similar a FindFirst y FindNext pero que devuelva los nombres de los archivos ordenados por fecha de creación o si hay alguna manera de que me devuelva los archivos más viejitos dentro del directorio y asi evitarme el ordenarlos pues ya sería una ayuda...

Bueno, ojalá puedan ayudarme y de antemano les agradezco...

Saludos y buen día
__________________
Herr Heins Faust
Responder Con Cita
  #2  
Antiguo 23-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Hola Faust,

Cuando he tenido que crear procedimientos muy parecidos a lo que comentas, he utilizado ClientsDataset para almacenar en memoria la información de los ficheros y así poder tratarla (ordernarla, locarlizar, comparar, etc).

Un problema que podrías tener al utilizar ClientDataset, como tablas temporales en memoria, es que cuando insertar muchos registros se quedan un poco lentos.

He probado a generar 130.000 registros en memoria y me ha tardado algo menos de un segundo.

En este caso, te diría que podrías utilizar un ClientDataset en memoria para manejar la información de tus ficheros.

Si decides probarlo, Hazle un ".MergeChangeLog", cada 100 insercciones, para que limpie "Basura interna"

Espero que te ayude.

Un saludo.
Responder Con Cita
  #3  
Antiguo 23-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Cita:
Empezado por manuc Ver Mensaje
Hola Faust,

Cuando he tenido que crear procedimientos muy parecidos a lo que comentas, he utilizado ClientsDataset para almacenar en memoria la información de los ficheros y así poder tratarla (ordernarla, locarlizar, comparar, etc).

Un problema que podrías tener al utilizar ClientDataset, como tablas temporales en memoria, es que cuando insertar muchos registros se quedan un poco lentos.

He probado a generar 130.000 registros en memoria y me ha tardado algo menos de un segundo.

En este caso, te diría que podrías utilizar un ClientDataset en memoria para manejar la información de tus ficheros.

Si decides probarlo, Hazle un ".MergeChangeLog", cada 100 insercciones, para que limpie "Basura interna"

Espero que te ayude.

Un saludo.

Vaya no sabía que pudiera usarse así un ClientDataSet, creí que solo funcionaban enlazados a bases de datos... perdón por abusar un poco de tu conocimiento, pero podrías poner un ejemplo sobre el uso de él de aunque sea 10 líneas si se puede y aunque no esté relacionado con mi problema...

Gracias

Ah, se me olvidaba una pregunta... es necesario instalar el BDE para utilizar el ClientDataSet, es que no quisiera instalarlo donde pongo la aplicación ya que es un servidor
__________________
Herr Heins Faust

Última edición por Faust fecha: 23-07-2010 a las 18:20:58.
Responder Con Cita
  #4  
Antiguo 23-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Sí, claro. Es muy sencillo.

Agregas un ClientDataset a tu formulario. Le haces doble clic y le agregas los campos que quieras, nombre del fichero, fecha de modificación, etc.

Cada uno con el tipo de dato que te interese y en la propiedad FieldKind, le dejas fkData.

Para inicializarlo:
Código Delphi [-]
ClientDataSet1.CreateDataSet;
ClientDataSet1.Open;

Y a partir de aquí como un Dataset normal que esté conectado a base de datos:

Código Delphi [-]
var
 c:Integer;
 empieza:TDateTime;
begin
empieza := Now;
for c:= 1 to 130000 do
    begin
    if c mod 100 = 0 Then
       ClientDataSet1.MergeChangeLog; //Limpiamos las copias internas que realiza el componente; Para este caso nos sirve de nada y ralentiza una barbaridad. 
    ClientDataSet1.Append;
    ClientDataSet1fichero.AsString := 'fichero '+inttostr(c);
    ClientDataSet1fecha.AsDateTime := Now;
    ClientDataSet1.Post;
    end;
ShowMessage('Ya ' +FormatDateTime('hh:nn:ss:zzz',Now-empieza));

Como ves es muy simple y te da mucha fuerza a la hora de manejar la información.

Si necesitas algo más o tienes alguna duda, coméntame sin problemas.

Un saludo.
Responder Con Cita
  #5  
Antiguo 23-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Muchas gracias, ya estoy trabajando en eso y la verdad es muy rápido, hasta es posible verlo en un DBGrid

Sabes si es necesario instalar el BDE o alguna librería en especial para usar ClientDataSet, DataSource y DBGrid, no quisiera instalarlos, pues esta aplicación debe correr en un servidor.

Muchísimas gracias y aquí estaré molestándote ...

Ah de paso te invito una cerveza, estas ya no te alertan con el antivirus...

__________________
Herr Heins Faust
Responder Con Cita
  #6  
Antiguo 23-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Smile

jeje, gracias por las cervezas, te las acepto, que aquí, ahora, hace mucha calor!!

Pues no tendrías que instalar nada. Simplemente añade a tus uses la unidad "MidasLib" y ya está.

Ciertamente lo puedes conectar a un dbGrid, pero ten en cuenta una cosa: si el Grid está activo las inserciones irán más lentas. Para evitar este problema, cuando vayas a insertar registros en el clientDataset hazle esto:
Código Delphi [-]
ClientDataset1.DisbleControls;
y cuando termines habilitalo de nuevo así.
Código Delphi [-]
ClientDataset1.EnableControls;

Un saludo.
Responder Con Cita
  #7  
Antiguo 23-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Oh si, eso ya lo he notado, pero al ejecutar me voy a ver los módulos que ocupa mi aplicación y veo que usa midas.dll... ojalá no sea problema y pueda copiarla y usarla sin pormenores.

gracias.
__________________
Herr Heins Faust

Última edición por Faust fecha: 23-07-2010 a las 19:25:27.
Responder Con Cita
  #8  
Antiguo 23-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Si te refieres al fichero Midas.dll, si incluyes la unidad MidasLib, en los uses (del primer formulario que se cargue) no necesitarás copiar la librería, se embebe en el propio ejecutable.

Saludos.
Responder Con Cita
  #9  
Antiguo 23-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Aquí estoy de nuevo con otra duda... ya puedo usarlo, es muy rápido, pero como le hago para usarlo por segunda vez, simplemente ejecutando ClientDataSet1.Close y volviéndolo a llenar???

Desde ya muchas gracias.
__________________
Herr Heins Faust
Responder Con Cita
  #10  
Antiguo 24-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Al cerrar y abrirlo: ¿Se te quedan los registros cargados en memoria?

Imagino que sí. Cosas del ClientDataset. Prueba ha hacer esto:

Código Delphi [-]
ClientDataSet1.Close;
ClientDataSet1.ProviderName := '-';
ClientDataSet1.ProviderName := '';
ClientDataSet1.CreateDataSet;
ClientDataSet1.Open;

El ClientDataset lleva una variable interna denominada Data, donde guarda todos los registros que vas cargando en memoria.

Al cambiar la propiedad PoviderName (o RemoteServer) internamente detecta que la información de Data puede haber cambiado y resetea la variable, perdiendo la estructura de datos y los propios datos (al hacer el .close, claro).

De esta forma, lo engañamos y podemos resetear el ClientDataset, para volver a cargarlo de nuevo.

Un saludo.
Responder Con Cita
  #11  
Antiguo 26-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Cita:
Empezado por manuc Ver Mensaje
Al cerrar y abrirlo: ¿Se te quedan los registros cargados en memoria?

Imagino que sí. Cosas del ClientDataset. Prueba ha hacer esto:

Código Delphi [-]ClientDataSet1.Close; ClientDataSet1.ProviderName := '-'; ClientDataSet1.ProviderName := ''; ClientDataSet1.CreateDataSet; ClientDataSet1.Open;


El ClientDataset lleva una variable interna denominada Data, donde guarda todos los registros que vas cargando en memoria.

Al cambiar la propiedad PoviderName (o RemoteServer) internamente detecta que la información de Data puede haber cambiado y resetea la variable, perdiendo la estructura de datos y los propios datos (al hacer el .close, claro).

De esta forma, lo engañamos y podemos resetear el ClientDataset, para volver a cargarlo de nuevo.

Un saludo.

Sale... muy buena solución, muchas gracias de nuevo amigo.
__________________
Herr Heins Faust
Responder Con Cita
Respuesta



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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Busqueda por fecha en FB2.0 david_uh Firebird e Interbase 4 18-07-2008 00:23:48
¿Búsqueda SQL por Fecha? lKinGl SQL 33 28-04-2008 19:33:41
Busqueda por fecha IBquery mjjj SQL 4 23-10-2007 20:36:47
Busqueda segun el mes de una fecha(no la fecha completa) federiconqn21 Firebird e Interbase 1 05-05-2006 15:39:53
Busqueda en un campo fecha seken Varios 7 14-04-2005 14:11:19


La franja horaria es GMT +2. Ahora son las 10:10:30.


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