escuchar fichero
#1
Posted 15 September 2010 - 11:44 AM
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
#2
Posted 15 September 2010 - 11:55 AM
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
#3
Posted 15 September 2010 - 11:56 AM
Salud OS
#4
Posted 15 September 2010 - 12:59 PM
#5
Posted 15 September 2010 - 01:02 PM
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
#6
Posted 15 September 2010 - 01:07 PM
Saludos
#7
Posted 15 September 2010 - 01:24 PM
\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!
#8
Posted 15 September 2010 - 01:29 PM
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,
#9
Posted 15 September 2010 - 01:49 PM
Salud OS
#10
Posted 15 September 2010 - 01:50 PM
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
#11
Posted 15 September 2010 - 02:02 PM
saludos
#12
Posted 15 September 2010 - 02:08 PM
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
#13
Posted 15 September 2010 - 03:30 PM
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:
case SHCNE_UPDATEDIR: SHGetPathFromIDList(ppidl[0], Path); if(*Path) Memo1->Lines->Add("Contenido de la carpeta cambiado: " + String(Path)); break; case SHCNE_MKDIR: SHGetPathFromIDList(ppidl[0], Path); if(*Path) Memo1->Lines->Add("Carpeta creada: " + String(Path)); break; case SHCNE_RMDIR: SHGetPathFromIDList(ppidl[0], Path); if(*Path) Memo1->Lines->Add("Carpeta borrada: " + String(Path)); break; case SHCNE_CREATE: SHGetPathFromIDList(ppidl[0], Path); if(*Path) Memo1->Lines->Add("Archivo nuevo: " + String(Path)); break; case SHCNE_DELETE: SHGetPathFromIDList(ppidl[0], Path); if(*Path) Memo1->Lines->Add("Archivo borrado: " + String(Path)); 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.
#14
Posted 15 September 2010 - 04:30 PM
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,
#15
Posted 16 September 2010 - 02:54 AM
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.
#16
Posted 16 September 2010 - 04:28 AM
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".
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"?!
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.
Saludos,
#17
Posted 16 September 2010 - 05:19 AM
un saludos y muchas gracias
#18
Posted 16 September 2010 - 06:57 AM
...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.
#19
Posted 16 September 2010 - 07:16 AM
Saludos