2009-09-19 12 views
18

Cuando llamo al FileInfo(path).LastAccessTime o FileInfo(path).LastWriteTime en un archivo que está en proceso de escritura, devuelve la hora de creación del archivo, no la última vez que se escribió (es decir, ahora)..NET FileInfo.LastWriteTime & FileInfo.LastAccessTime son incorrectos

¿Hay alguna manera de obtener esta información?

Editar: A todas las respuestas hasta ahora. No había intentado Refresh(), pero eso tampoco lo hace. Me devolvieron la hora en que se comenzó a escribir el archivo. Lo mismo ocurre con el método estático y la creación de una nueva instancia de FileInfo.

Codymanix puede tener la respuesta, pero no estoy ejecutando Windows Server (con Windows 7), y no sé dónde se realizará la prueba.

Editar 2: ¿A nadie le parece interesante que esta función no parezca funcionar?

+0

También he encontrado que estas funciones proporcionan información no confiable; como cuando el archivo reside en un recurso compartido de red (samba). Noté que los documentos de MSDN (http://msdn.microsoft.com/en-us/library/system.io.file.getlastaccesstime(v=VS.90).aspx) ahora dicen "Este método puede devolver un valor inexacto ... . " –

Respuesta

3

¿Ha intentado llamar al Refresh() justo antes de acceder a la propiedad (para evitar obtener un valor en caché)? Si eso no funciona, ¿has mirado lo que Explorer muestra al mismo tiempo? Si Explorer muestra la información incorrecta, probablemente sea algo que no se pueda abordar realmente; es posible que la información solo se actualice cuando se cierra el identificador del archivo, por ejemplo.

14

Los valores FileInfo solo se cargan una vez y luego se guardan en caché. Para obtener el valor actual, llamar Refresh() antes de conseguir una propiedad:

f.Refresh(); 
t = f.LastAccessTime; 

Otra forma de obtener el valor actual es el uso de los métodos estáticos en la clase File:

t = File.GetLastAccessTime(path); 
+0

t = File.GetLastAccessTime (ruta); todavía está desactualizado si un proceso se ha guardado pero está bloqueando el archivo. Esta respuesta es incorrecta. – rolls

4

De MSDN:

Cuando se invoca por primera vez, FileSystemInfo llama a Refresh y devuelve la información en caché de en las API para obtener atributos y demás. En las llamadas posteriores , debe llamar a Refresh para obtener la última copia de la información.

FileSystemInfo.Refresh()

Si estás aplicación es el que hace la escritura, creo que va a tener que "toque" el archivo estableciendo la propiedad LastWriteTime su auto entre cada búfer de datos se escribe . Algunos psuedocode:

while(bytesWritten < totalBytes) 
{ 
    bytesWritten += br.Write(buffer); 
    myFileInfo.LastWriteTime = DateTime.Now; 
} 

no estoy seguro de qué tan gravemente que esto afectará el rendimiento de escritura.

4

Hay una configuración en Windows que a veces se configura especialmente en los sistemas de servidor, de modo que los tiempos modificados y accedidos para los archivos no están configurados para un mejor rendimiento.

+0

codymanix tiene razón, hablan de esta configuración aquí: http://blogs.technet.com/b/filecab/archive/2006/11/07/disabling-last-access-time-in-windows-vista-to- improve-ntfs-performance.aspx – DukeOfMarmalade

+0

Ese enlace solo menciona la última hora modificada. –

0

respuesta de Tommy Carlier me hizo pensar ....

Una buena forma de visualizar las diferencias es ejecutando por separado los dos fragmentos (acabo de utilizar LinqPAD) similar a los de abajo mientras también ejecuto el monitor de proceso sysinternals.

while(true) 
    File.GetLastAccessTime([file path here]); 

y

FileInfo bob = new FileInfo(path); 

while(true){ 
    string accessed = bob.LastAccessTime.ToString(); 
} 

Si nos fijamos en el monitor de procesos mientras se ejecuta el primer fragmento de código que verá repetidos y constantes intentos de acceso al archivo para el proceso LINQPad. El segundo fragmento hará un acceso inicial al archivo, para lo cual verá actividad en el monitor del proceso, y luego muy poco después.

Sin embargo, si va y modifica el archivo (acabo de abrir el archivo de texto que estaba monitoreando usando FileInfo y agregué un carácter y guardé) verá una serie de intentos de acceso al proceso en el monitor de proceso de LinqPAD.

Esto ilustra el comportamiento no en caché y en caché de las dos aproximaciones diferentes, respectivamente.

¿El enfoque sin memoria caché tendrá un agujero en el disco duro?

EDITAR

me fui sintiendo todo inteligente sobre mis pruebas y luego se usa el comportamiento de almacenamiento en caché de FileInfo en mi servicio de Windows (básicamente para sentarse en un bucle y decir 'Has-archivo-cambiado-ha- archivo-cambiado ... 'antes de hacer el procesamiento)

Si bien este enfoque funcionó en mi cuadro dev, no funcionó en el entorno de producción, es decir, el proceso siguió ejecutándose sin importar si el archivo había cambiado o no. Terminé cambiando mi enfoque para verificar y solo utilicé GetLastAccessTime como parte de él. No sé por qué se comportaría de manera diferente en el servidor de producción ... pero no estoy demasiado preocupado en este momento.

+0

Eventualmente sí, así como el tiempo y el espacio. – PsyKzz

2

Como James ha señalado, LastAccessTime no está actualizado.

El LastWriteTime también ha sufrido un giro desde Vista. Cuando el proceso tiene el archivo aún abierto y otro proceso comprueba el LastWriteTime, no verá el nuevo tiempo de escritura durante un tiempo prolongado hasta que el proceso haya cerrado el archivo. Como solución alternativa puede abrir y cerrar el archivo de su proceso externo. Después de haber hecho eso, puede intentar leer LastWriteTime nuevamente, que es el valor actualizado.

Si una aplicación implementa algo así como un registrador móvil que cierra el archivo y luego lo renombra con un nombre de archivo diferente también se encontrará con problemas ya que el sistema operativo recuerda el tiempo de creación y el tamaño del archivo "anterior" aunque creaste un nuevo archivo. Esto incluye informes incorrectos del tamaño del archivo, incluso si rectaste log.txt desde cero, que aún tiene 0 bytes de tamaño. Esta función se llama OS File System Tunneling, que todavía está presente en Windows 8.1. Un ejemplo de cómo implementar este problema, echa un vistazo a RollingFlatFileTracelistener de Enterprise Library (http://home.elka.pw.edu.pl/~mrudnik/CREAM/Logging/Src/Logging/TraceListeners/RollingFlatFileTraceListener.cs).

Puede ver los efectos del túnel del sistema de archivos en su propia máquina desde el shell de cmd.

echo test > file1.txt 
ren file1.txt file2.txt 
Wait one minute 
echo test > file1.txt 

dir /tc file*.txt 
... 
05.07.2015 19:26     7 file1.txt 
05.07.2015 19:26     7 file2.txt 

El sistema de archivos es una máquina de estado. Mantener los estados correctamente sincronizados es difícil si le importa el rendimiento y la corrección. Este extraño síndrome de tunelización sigue siendo utilizado por aplicaciones que, p. guarde automáticamente un archivo y muévalo a una ubicación de guardado y luego vuelva a crear el archivo en la misma ubicación. Para estas aplicaciones, tiene sentido dar al archivo una nueva fecha de creación porque solo se copió. Algunos instaladores también hacen tales trucos para mover archivos temporalmente a una ubicación diferente y escribir los contenidos más tarde para pasar algún archivo existente y comprobar si hay algunos ganchos de instalación.

Cuestiones relacionadas