Ir al contenido



Foto

escuchar fichero


  • Por favor identifícate para responder
18 respuestas en este tema

#1 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 septiembre 2010 - 11:44

hola foro, amigos lo que intento hacer es lo siguiente:
Desde mi aplicación tengo un memo el cual carga la información de un fichero.txt
pero el fichero.txt es modificado por otra aplicación externa, no quisiera poner un timer en mi proyecto para actualizar el memo, sino que quisiera saber de que forma mi app puede saber cuando se actualiza ese fichero txt y cargar el memo cuando el txt sufra cambios. No se si me supe explicar , se que fue algo enredado.
espero me puedan ayudar.
Gracias
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 11:55

hola foro, amigos lo que intento hacer es lo siguiente:
Desde mi aplicación tengo un memo el cual carga la información de un fichero.txt
pero el fichero.txt es modificado por otra aplicación externa, no quisiera poner un timer en mi proyecto para actualizar el memo, sino que quisiera saber de que forma mi app puede saber cuando se actualiza ese fichero txt y cargar el memo cuando el txt sufra cambios. No se si me supe explicar , se que fue algo enredado.
espero me puedan ayudar.
Gracias


Lo mejor de Delphi es su utilización del API de Windows, por lo que te proveé de un componente que se llama TShellChangeNotifier este componente te "avisa" de cualquier cambio dentro de un directorio (que tu puedes definir) ya sea nuevos archivos, directorios, cambios de nombre, cambios de Tamaño de archivo.

Este componente no se instala por Default, tendrás que instalarlo, la ubicación de este componente depende de la versión que tengas de Delphi pero suele estar en el directorio Demos\DelphiWin32\VCLWin32\ShellControls donde encontrarás dos paquetes:

dclshlctrls.dpk y vclshlctrls.dpk

Son muy útiles.

Salud OS

  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 11:56

Por cierto, lo has colocado en el foro de  Otros Lenguajes (C, C++, Java, ASM), lo siento si no era para Delphi, pero puedes buscar sobre el API de este componente....

Salud OS
  • 0

#4 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 septiembre 2010 - 12:59

hola egostar, gracias por responder. El tema es para C++Builder, perdón por eso, pero no comprendo..estas queriéndome decir que hay un  componente que hace esto?
  • 0

#5 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 01:02

hola egostar, gracias por responder. El tema es para C++Builder, perdón por eso, pero no comprendo..estas queriéndome decir que hay un  componente que hace esto?


En Delphi si, no se si en C++ Builder lo tiene.

Y me refería a que el componente viene del API de windows, así que utilizando el API puedes hacer lo que quieras, aquí nuestro amigo escafandra nos puede ayudar mas. ;)

Salud OS
  • 0

#6 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 septiembre 2010 - 01:07

muchas gracias egostar, espero que escafandra nos pueda ayudar también.
Saludos
  • 0

#7 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 septiembre 2010 - 01:24

egostar yo estoy trabajando con el codegear rad studio 2010  y en
\Demos\CPP\Apps\ShellControls estaba el ejemplo que me decías compile y se me agrego un nuevo componente a la paleta Samples llamado: ShellChangeNotifier
y por lo que veo trae buienas opciones, estaré probandolas y luego te comento si funcionan.
un millón de gracias
Adelante con este foro!
  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.259 mensajes
  • LocationArgentina

Escrito 15 septiembre 2010 - 01:29

Al menos en D6 Enterprise viene instalado  ;)
El asunto es que cuando quise ver la ayuda sobre dicho componente me doy con que no hay nada.  :( ¿O será que la ayuda de este componente hay que instalarla a mano? NO me he fijado... nunca lo he utilizado.

Ahora mi pregunta es ¿Cómo identificar el fichero que ha cambiado? Porque lo que veo es que pide indicar un directorio, una carpeta. No me deja seleccionar un archivo.  :(

Si es que se trata de hacer una especie de hook a la Shell de Windows, entonces creo que el primer lugar al menos para irse documentando es éste.

Saludos,
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 01:49

Efectivamente amigo Delphius, solo te dice que hubo algún cambio dentro del directorio ROOT que indicas, pero nada que no se pueda resolver ;), yo lo uso con muy buenos resultados y no sobrecargo mis procesos con búsquedas periódicas al directorio, es decir, evalúas el costo/beneficio de usar uno y otro. ;)

Salud OS
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 01:50

egostar yo estoy trabajando con el codegear rad studio 2010  y en
\Demos\CPP\Apps\ShellControls estaba el ejemplo que me decías compile y se me agrego un nuevo componente a la paleta Samples llamado: ShellChangeNotifier
y por lo que veo trae buienas opciones, estaré probandolas y luego te comento si funcionan.
un millón de gracias
Adelante con este foro!


Que bien, te será de mucha ayuda.

Salud OS
  • 0

#11 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 septiembre 2010 - 02:02

delphius estoy de acuerdo contigo, el problema ahora seria saber que fichero dentro del directorio fue modificado?
saludos
  • 0

#12 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.966 mensajes
  • LocationMéxico

Escrito 15 septiembre 2010 - 02:08

delphius estoy de acuerdo contigo, el problema ahora seria saber que fichero dentro del directorio fue modificado?
saludos


Puedes indicarle que solo te notifique los cambios de tamaño y cargas directamente el archivo que ya sabes y probar si con eso es suficiente.

La pregunta es si ese directorio contiene muchos archivos que cambian de tamaño .....

Salud OS
  • 0

#13 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.849 mensajes
  • LocationMadrid - España

Escrito 15 septiembre 2010 - 03:30

Efectivamente desde la versión 6 de Builder existe ese control, TShellChangeNotifier. Aunque queda escondido como "no muy oficial".

No hace mucho, publique la forma de realizar eso directamente con la API de WIndows: Monitorizando el Shell sólo con la API. En concreto el uso de los identificadores de eventos del Shell:
SHCNE_UPDATEDIR
SHCNE_CREATE
SHCNE_DELETE

Como el ejemplo de este fragmento de mi código:


cpp
  1.       case SHCNE_UPDATEDIR:
  2.         SHGetPathFromIDList(ppidl[0], Path);
  3.         if(*Path)
  4.             Memo1->Lines->Add("Contenido de la carpeta cambiado: " + String(Path));
  5.       break;
  6.       case SHCNE_MKDIR:
  7.         SHGetPathFromIDList(ppidl[0], Path);
  8.         if(*Path)
  9.             Memo1->Lines->Add("Carpeta creada: " + String(Path));
  10.       break;
  11.       case SHCNE_RMDIR:
  12.         SHGetPathFromIDList(ppidl[0], Path);
  13.         if(*Path)
  14.             Memo1->Lines->Add("Carpeta borrada: " + String(Path));
  15.       break;
  16.       case SHCNE_CREATE:
  17.         SHGetPathFromIDList(ppidl[0], Path);
  18.         if(*Path)
  19.             Memo1->Lines->Add("Archivo nuevo: " + String(Path));
  20.       break;
  21.       case SHCNE_DELETE:
  22.         SHGetPathFromIDList(ppidl[0], Path);
  23.         if(*Path)
  24.             Memo1->Lines->Add("Archivo borrado: " + String(Path));
  25.       break;

Ahora que sabes que la carpeta cambió o que tu archivo se borró o creó, sólo tienes que buscarlo y ver si su fecha de modificación es mas o menos moderna de lo esperado, y sabrás si se modificó.
En este truco tienes la fecha de creación y modificación de un fichero.

Espero haber arrojado algo de luz.

Saludos.


  • 0

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.259 mensajes
  • LocationArgentina

Escrito 15 septiembre 2010 - 04:30

Hola, Gracias escafrandra por aportar luz al asunto,

Déjame ver si entiendo... ¿entonces no hay un identificador propio que sea capaz de informar si un archivo ha cambiado en cuanto a tamaño, fecha, etc?

A como lo veo tal parece que entonces debe hacerse en combinación de algunos identificadores y examinar cada cosa para comprobar QUE o EN QUE es lo que ha cambiado.

Estoy viendo la lista de identificadores y noto que está SHCNE_UPDATEITEM, que al parecer es el que permite indicar que ha cambiado un item... El asunto es que de lo poco que estoy entiendiendo... ¿este identificador hace referencia sólo cuando se cambia el nombre? Porque en la documentación dice:

but the item still exists and has not been renamed


Por otro lado también estoy viendo que existe un identificador para los cambios en el espacio libre: SHCNE_FREESPACE.

Saludos,
  • 0

#15 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.849 mensajes
  • LocationMadrid - España

Escrito 16 septiembre 2010 - 02:54


Déjame ver si entiendo... ¿entonces no hay un identificador propio que sea capaz de informar si un archivo ha cambiado en cuanto a tamaño, fecha, etc?

Así parece. Ningún indicador parece diseñado para avisar del cambio del contenido de un archivo así que sólo cabe comparar la fecha de modificación a su contenido mismo... Pero si nos avisará de que el contenido de la carpeta que lo contiene se ha alterado. Dado el aviso nos ponemos manos a la obra pava ver que archivo se ha tocado.
 

 


Estoy viendo la lista de identificadores y noto que está SHCNE_UPDATEITEM, que al parecer es el que permite indicar que ha cambiado un item... El asunto es que de lo poco que estoy entiendiendo... ¿este identificador hace referencia sólo cuando se cambia el nombre?

Parecería que ese indicador promete avisar del cambio de contenido del archivo pero en realidad no avisa de ese cambio ni del cambio de nombre, sino de otros aspectos variopintos, incluso de que se desconecta el cable de red.

Experimenta con el código que dejé.  ;)


Saludos.


  • 0

#16 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.259 mensajes
  • LocationArgentina

Escrito 16 septiembre 2010 - 04:28

Así parece. Ningún indicador parece diseñado para avisar del cambio del contenido de un archivo así que sólo cabe comparar la fecha de modificación a su contenido mismo... Pero si nos avisará de que el contenido de la carpeta que lo contiene se ha alterado. Dado el aviso nos ponemos manos a la obra pava ver que archivo se ha tocado.

Entonces es casi lo mismo como si examinaramos "a mano". Lo único "nuevo" es que nos dice... "Oye, que algo ha cambiado aquí pero no que carajos es".  :D
 

Parecería que ese indicador promete avisar del cambio de contenido del archivo pero en realidad no avisa de ese cambio ni del cambio de nombre, sino de otros aspectos variopintos, incluso de que se desconecta el cable de red.

¡Vaya, encima de que no sabe en que decir que se ha cambiado se atreve a decir... "¿Porqué no miras el condesador de flujo a ver si es eso"?!  :D

Con razón ni el mismo Windows se entiende...
 

Experimenta con el código que dejé.  ;)

Saludos.

Pues habrá que "jugar" un rato.

Si no vuelvo en unas horas es porqué toqué el condensador de flujo y me mandé al pasado a ayudar al doc a evitar que Bill domine el mundo.
Es eso o.... mandarme al pasado para evitar que encuentre en mi biblioteca "Guía introductoria a Linux para principiantes" y ponerme a leerlas durante las noches... Creo que ya estoy teniendo pesadillas.  :p

Saludos,


  • 0

#17 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 16 septiembre 2010 - 05:19

Amigo muchas gracias por las respuestas al tema, estuve viendo los aportes de escafandra (lastima que no esta en c++). Creo que utilizare el componente y en mi caso sera un caso sencillo, porque se el fichero que tengo que monitorizar y se en que carpeta se encuentra, es solo percibir un cambio y preguntar por el fichero. Creo que el tema se podría estudiar mas para saber que fichero se modifico, yo no por supuesto no soy ducho en estos temas, pero el amigo scafandra y demás se que si.
un saludos y muchas gracias
  • 0

#18 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.849 mensajes
  • LocationMadrid - España

Escrito 16 septiembre 2010 - 06:57

...estuve viendo los aportes de escafandra (lastima que no esta en c++).


Para completar el truco y saciar tu curiosidad he publicado una versión en C++ Builder

Saludos.


  • 0

#19 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 16 septiembre 2010 - 07:16

escafandra mil gracias por el código, fenomenal... haré mis pruebas y veré la conveniencia de utilizar el código o el componente. Aunque creo que utilizar el código me ayudaría mas a comprender y reduciría el tamaño del exe.
Saludos
  • 0