Necesito crear un programa java que creará un hilo para buscar un archivo en una carpeta particular (carpeta fuente) y recoger el archivo inmediatamente para el proceso (convertirlo a formato de archivo csv) una vez que encuentre el archivo en el Carpeta de origen. Problema al que me enfrento ahora es que el archivo que llega a la carpeta de origen es de gran tamaño (la herramienta FTP se usa para copiar archivos del servidor a la carpeta de origen), thread está escogiendo ese archivo inmediatamente antes de copiarlo completamente a la carpeta fuente y lanzar una excepción. ¿Cómo detengo el hilo hasta que el archivo se copia completamente en la carpeta de origen? Tiene que elegir el archivo para procesarlo solo después de que el archivo se haya copiado por completo en la carpeta de origen.¿Cómo se manejan los archivos incompletos? Obteniendo la excepción
Respuesta
Suponiendo que haya ningún control sobre el proceso de FTP ...
Que sea así. Cuando obtenga la excepción, intente procesarla nuevamente la próxima vez. Repítalo hasta que el archivo sea procesado. Es bueno tener pocos atributos en caso de excepción para comprobarlo más tarde, como; nombre, última modificación, tamaño.
Compruebe la excepción exacta antes de decidir procesarla más adelante, la excepción puede ocurrir por algún otro motivo.
Si tiene algún control sobre el proceso que realiza el FTP, es posible que tenga que crear un "archivo de marca" en el directorio de origen inmediatamente DESPUÉS de que termine el ftp para el archivo grande.
Luego, su subproceso Java tiene que verificar la presencia de este archivo de indicador, si está presente, entonces hay un archivo listo para ser procesado en el directorio de origen. Antes de procesar el archivo grande, el hilo debe eliminar el archivo de indicador.
El archivo de marca puede ser cualquier cosa (incluso un archivo vacío).
Usted podría intentar cosas diferentes:
-
comprobar varias veces la fecha de la última modificación y el tamaño del archivo hasta que no cambia más de una determinada cantidad de tiempo, y luego procesarla.(Como lo señala qbeuek, esto no es seguro ni determinista.) - Solo procesa archivos con nombres que coinciden con ciertos criterios (por ejemplo, * .dat). Cambie el proceso de carga/descarga de FTP para cargar/descargar archivos con un nombre diferente (por ejemplo, * .dat.temp) y cambie el nombre de los archivos una vez que se hayan completado.
- Descargue los archivos en una ubicación diferente y muévalos a su directorio de procesamiento una vez que estén completos.
- Como dijo Vinegar, si no funciona la primera vez, inténtelo más tarde. :)
No sé por qué tenemos votos a favor, a veces. La gente comienza a dispararlo a todas partes. 100 reputación es demasiado baja para vengar a alguien. Debe ser mayor, puede ser 1000 o 2000. –
Bueno, a veces voto cosas solo para equilibrar los votos a la baja, dando al voto +8 puntos que de otra manera no recibirían, eso es algo. En este caso, hubiera votado tu respuesta de todos modos, difícil. – itsadok
te he votado negativamente, porque el primer elemento de tu lista de sugerencias no es seguro ni determinista. – qbeuek
La forma más segura es descargar el archivo a una ubicación diferente y luego moverlo a la carpeta de destino.
Otra variación mencionada por Bombe es cambiar el nombre del archivo a alguna otra extensión después de la descarga y buscar solo archivos con esa extensión.
+1 Esta no es la manera más segura, pero la única forma de hacerlo. Todas las demás opciones desperdician recursos o son inseguras :) –
Solo leo el archivo que no está en modo de escritura. Esto es más seguro ya que significa que no hay otro proceso escribiendo en este archivo. Puede verificar si el archivo no está en modo de escritura utilizando el método canWrite de la clase File.
Esta solución funciona bien para mí, ya que también tengo exactamente el mismo escenario al que se enfrenta.
Si su sistema operativo es Linux, y su kernel> 2.6.13, puede usar la API de notificación de eventos del sistema de archivos llamada inotify. Hay una implementación de Java aquí: https://bitbucket.org/nbargnesi/inotify-java.
Aquí hay un código de muestra (fuertemente inspirado en el sitio web).
try {
Inotify i = new Inotify();
InotifyEventListener e = new InotifyEventListener() {
@Override
public void filesystemEventOccurred(InotifyEvent e) {
System.out.println("inotify event occurred!");
}
@Override
public void queueFull(EventQueueFull e) {
System.out.println("inotify event queue: " + e.getSource() +
" is full!");
}
};
i.addInotifyEventListener(e);
i.addWatch(System.getProperty("user.home"), Constants.IN_CLOSE_WRITE);
} catch (UnsatisfiedLinkError e) {
System.err.println("unsatisfied link error");
} catch (UserLimitException e) {
System.err.println("user limit exception");
} catch (SystemLimitException e) {
System.err.println("system limit exception");
} catch (InsufficientKernelMemoryException e) {
System.err.println("insufficient kernel memory exception");
}
Esto está en Grails y estoy usando FileUtils
Biblioteca de la fama Commons Apache. La función sizeof
devuelve el tamaño en bytes.
def fileModified = sourceFile.lastModified()
def fileSize = FileUtils.sizeOf(sourceFile)
Thread.sleep(3000) //sleep to calculate size difference if the file is currently getting copied
if((fileSize != FileUtils.sizeOf(sourceFile)) && (fileModified != sourceFile.lastModified())) //the file is still getting copied to return
{
if(log.infoEnabled)
log.info("File is getting copied!")
return
}
Thread.sleep(1000) //breather for picking up file just copied.
Tenga en cuenta que esto también depende de lo que la utilidad o el sistema operativo que está utilizando para transferir los archivos. La apuesta más segura es copiar el archivo que se ha copiado o se ha copiado a un archivo o directorio diferente. El proceso de copia es robusto y le asegura que el archivo está presente después del proceso de copiado. El que estoy usando proviene de la API de commons.
FileUtils.copyFileToDirectory (f Archivo, Directorio D)
Si va a copiar un archivo enorme que está en proceso de ser copiado ten en cuenta que esto llevará tiempo y que le gustaría empezar este hilo en paralelo o mejor tener una aplicación separada dedicada para el proceso de transferencia.
- 1. ¿Cómo se manejan los nombres de archivos con espacios?
- 2. ¿Cómo se manejan los subproyectos con autotools?
- 3. ¿Cómo se manejan múltiples archivos web.config para múltiples entornos?
- 4. ¿Cómo se manejan los repositorios grandes de git?
- 5. ¿Cómo se manejan los datos R internos de un paquete?
- 6. ¿Cómo se manejan las asociaciones entre los agregados en DDD?
- 7. ¿Cómo manejan los accesorios Django ManyToManyFields?
- 8. ¿Cómo no se manejan los resultados en LINQ?
- 9. ¿Cómo se manejan los nulos en LINQ cuando se usa Min o Max?
- 10. ¿Cómo se manejan varias instancias de setTimeout()?
- 11. ¿Cómo se manejan las interrupciones en SMP?
- 12. SharpSvn: Obteniendo la estructura del repositorio y los archivos individuales
- 13. ¿Cómo se manejan las cadenas en C++?
- 14. ¿Cómo se manejan las funciones cpp?
- 15. ¿Cómo se manejan los pagos sin usarlos en la compra de la aplicación en aplicaciones ios?
- 16. Los archivos enviados con ssh2_scp_send() están incompletos en el servidor remoto
- 17. Obteniendo una excepción como "La colección se mutó mientras se estaba enumerando"
- 18. ¿Cómo se manejan dos personas, editando simultáneamente el mismo archivo?
- 19. Obteniendo la excepción EOF sobre la llamada https
- 20. ¿Cómo se manejan las excepciones "imposibles" en Java?
- 21. ¿Los servidores de almacenamiento en Django manejan la eliminación de viejos archivos estáticos?
- 22. ¿Cómo se manejan los eventos de pulsación de tecla en una aplicación de la consola Qt?
- 23. Recursos de Android: ¿Cómo se manejan los mapas de bits de los recursos manejados en memoria?
- 24. ¿Cómo se manejan diferentes IDEs Java y svn?
- 25. ¿Cómo se manejan los mensajes de los controles creados dinámicamente en una aplicación MFC?
- 26. ¿Cómo se manejan las versiones en una aplicación web?
- 27. ¿Cómo se manejan los datos de "casos especiales" cuando se modela una base de datos?
- 28. ¿Cómo se manejan los tipos mixtos cuando se implementan operadores de comparación?
- 29. ¿Cómo se manejan los meta elementos que no se validan en HTML5?
- 30. ¿Se me permite tener agregados "incompletos" en DDD?
Es bueno saber, ¿qué excepción? –