File.exists () devuelve falso cuando el archivo existe

90

Me he encontrado con un error que parece que no puedo encontrar ninguna lógica detrás. Tengo este objeto File, que se crea así:

File file = new File("utilities/data/someTextFile.txt");

Entonces lo hago file.exists(), y vuelve false(!?). Si no se encuentra el archivo, estoy ingresando f.getAbsolutePath()a un archivo. Cuando miro el camino, parece estar bien. Puedo copiar y pegar la ruta completa en la ventana "Ejecutar" en Windows y el archivo se abre bien.

El archivo existe en todo momento y no se elimina ni se modifica durante la ejecución de mi aplicación. Se encuentra en la máquina local.

Esto solo parece ocurrir en determinadas situaciones. Puedo reproducir el error en cualquier momento, pero estoy seguro de que las acciones que realizo para reproducir el error no modifican la ruta del objeto de archivo.

¿Qué puede causar file.exists()que se devuelva falso? ¿Tiene esto algo que ver con permisos o bloqueos de archivos, etc.?

atsjoo
fuente
Entonces, ¿es posible leer desde el archivo incluso si existe () devuelve falso?
Harry Lime
sí, puedo leer desde el archivo incluso si existe () devuelve falso.
atsjoo
1
¿Qué se necesita exactamente para reproducir la falla?
user85421
1
Esto está dentro de una aplicación que llama a funciones escritas en matlab y compiladas en la aplicación java. Parece que las funciones de matlab que cambian el "directorio actual" están causando que aparezca el problema. Estoy usando la ruta absoluta al crear el objeto de archivo, por lo que esto no debería ser un problema, como parece. Por supuesto, he verificado la ruta absoluta del objeto de archivo y es correcta (igual que antes de que la función matlab cambiara el directorio actual).
atsjoo
7
¿Está por casualidad trabajando contra un directorio remoto (por ejemplo, un montaje NFS)?
Tomer Gabel

Respuestas:

42

Veo la siguiente situación en Windows 7:

file.exists() == false
file.getAbsoluteFile().exists() == true

El archivo en cuestión es "var \ log", la ruta absoluta se refiere a un archivo existente que está en un subdirectorio normal (no en una tienda virtual). Esto se ve desde el IDE.

Roman Zenka
fuente
16
Lo acabo de descubrir: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Aparentemente, las operaciones que se ejecutan en el archivo se resuelven en el directorio actual, mientras que getAbsolutePath se resuelve en user.dir. Si estas dos rutas no coinciden, obtendrá resultados contradictorios. ¡Diabólico!
Roman Zenka
3
Tengo exactamente el mismo problema. Intenté usar ambos métodos para verificar si el archivo existe, ¡y aún obtengo falso en Windows 7 solamente! ¿Alguna idea?
Dejell
@Odelya: ¿Qué IDE estás usando? ¿En qué está configurado su -Duser.dir? Mi problema fue causado por configurar -Duser.dir en un directorio diferente al que funciona actualmente.
Roman Zenka
1
Para cualquiera que esté trabajando en un proyecto web dinámico, el uso de file.exists () generará una excepción, use file.getAbsoluteFile (). Existe () para buscar archivos en el directorio WEB-INF (consejo general, no específico de Windows 7 ).
PS
Considere la posibilidad de crear un control de calidad separado para esta respuesta y comentarios
Bato-Bair Tsyrenov
17

Parece que hay una diferencia en cómo se especifica la ruta en Java.

Por ejemplo, si la ruta del archivo se especifica como file:/C:/DEV/test.txtentonces

File f = new File(filename);
f.exists();

volverá false. La ruta puede funcionar en el explorador o en el navegador, pero es una URL y no una ruta de archivo absoluta.

Pero, por otro lado, si la ruta del archivo se especifica como C:/DEV/test.txtentonces

File f = new File(filename);
f.exists();

volverá trueporque la ruta no es una URL, pero es una ruta absoluta.

Con Spring Framework eso es exactamente lo que ResourceUtils.getFile(filename)hace, donde el nombre puede ser una URL o la ruta absoluta del archivo.

Garima Bathla
fuente
5
No esperaría file:/C:/DEV/test.txttrabajar como nombre de ruta. Es una URL, no un nombre de ruta. Si bien algunas personas cometen este error, no hay evidencia de que el OP haya ...
Stephen C
15

Si el proceso no tiene permisos para saber si un archivo existe, devolverá falso. Puede que sea posible abrir un archivo, pero no saber con los métodos normales si existe.

Tom Hawtin - tackline
fuente
20
Interesante. ¿Puedes ampliar esto? ¿Qué permisos específicos tienes en mente?
Clément
Aquí puede estar la capacidad de bloqueo de java.nio.file.AccessDeniedException para alcanzar la existencia de archivos / directorios. Por ejemplo, si mantiene dir abierto en FAR u otro explorador de archivos, luego elimine dir con todos los archivos anidados y verifique la existencia de este directorio, entonces puede obtener AccessDeniedException (extiende IOException) para el archivo temporal guardado para usted. En este caso, Files.exists devuelve falso para IOException.
beluha
11

Las respuestas anteriores no ayudaron en mi caso. Como se indicó anteriormente, tuve:

file.exists() => false
file.getAbsoluteFile().exists => true

La causa principal de esto fue que el propietario de la máquina con Windows 7 había modificado el registro de CMD para que ejecutara automáticamente un comando para iniciarlo en un directorio específico para trabajar con Python. Esta modificación paralizó el código Java 1.6 que aparentemente usa CMD en Windows para ciertas operaciones de archivos, como exists(). La eliminación de la ejecución automática del registro resolvió el problema.

Karl Lew
fuente
1
3,5 años después, me encontré con el mismo problema. Tenía un script de ejecución automática configurado para configurar las variables de entorno cada vez que iniciaba cmd.com. Ni siquiera cambió el directorio actual, solo algunas macros de doskey y algunas variables de entorno. Eliminé la ejecución automática y simplemente ejecuté manualmente los comandos en el archivo, y de repente File.exists () funciona correctamente.
Homr Zodyssey
1
Dios mío, realmente funciona (ambos), estaba buscando tontamente el archivo equivocado y encontré esta pregunta para descubrir por qué ninguno de ellos funciona para mí :) Por cierto, parece que ()faltan en la segunda línea después exists; )
RAM237
3

Obviamente, hay una serie de posibles causas y las respuestas anteriores las documentan bien, pero así es como resolví esto en un caso particular:

Un estudiante mío tuvo este problema y casi me arranco el cabello tratando de resolverlo. Resultó que el archivo no existía, aunque parecía que sí. El problema era que Windows 7 estaba configurado para "Ocultar extensiones de archivo para tipos de archivo conocidos". Esto significa que si el archivo parece tener el nombre "data.txt", su nombre de archivo real es "data.txt.txt".

Espero que esto ayude a otros a salvarse un poco de cabello.

petehern
fuente
No creo que este sea el problema en mi caso. Como mencioné en mi pregunta: "Puedo copiar y pegar la ruta completa en la ventana" Ejecutar "en Windows y el archivo se abre bien", lo que significa que el archivo realmente existe.
atsjoo
3

El new Filecomando simplemente crea una instancia de un archivo usando el nombre de ruta dado. En realidad, no crea un archivo en el disco duro.

Si usted dice

File file = new File ("path");
file.exists() 

Esto puede devolver verdadero solo si había un archivo existente con la misma ruta. Si pretendía comprobar el mismo archivo declarado en la primera línea, es posible que deba utilizarlo de esta forma.

File file = new File ("path");
file.createNewFile();
file.exists();

Ahora esto volverá a ser verdad.

R1234
fuente
pequeña explicación: cada llamada al constructor mediante el uso de una nueva palabra clave crea un Objeto, lo mismo que en este caso un Objeto descrito por Clase cuyo nombre es Archivo! ¡así que no es una instancia de File! = descriptors :)
ceph3us
3

Si no quiere lidiar con las llamadas getAbsoluteFile () cada vez que tiene que llamar a un método, es mejor que cree su instancia de archivo ya con una ruta absoluta. Esto debería funcionar:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

Sugiero rodearlo con un bloque try-catch, por cierto.

Fran Marzoa
fuente
3

Para generalizar el problema, surge el problema al convertir URL / URI en rutas locales.

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

Espero que esto ayude.

Arun
fuente
2

Cuando se marca ["Ocultar extensiones para tipos de archivo conocidos."], Las ventanas abren "t.txt.txt" cuando se escribe "t.txt" en [explorador] / [ejecutar Windows] pero no mediante programación.

yo también
fuente
1
Tuve este problema, y ​​el problema fue que creé un archivo txt, que se llamó 'testFile.txt', en C: \ test. Me referí a este archivo usando la ruta C: \ test \ testFile.txt, que no funcionó. Fue porque el archivo en realidad se había guardado como testFile.txt.txt, de ahí el voto a favor de la solución anterior (¡Pregunta anterior, pero no hay respuesta aceptada!)
Theblacknight
Dios Windows apesta tanto.
aafc
0

Buenas respuestas a todos. Descubrí que esto parece ser un problema con el acceso de Java al C:directorio raíz en Windows. Cualquier otro directorio debe estar bien, pero por alguna razón, mencionando específicamente C:\o C:o C:/podría dar un error. He resuelto este problema muy similar interceptando la mención new File("C:");y reemplazándolo con nuevo File(System.getProperty("file.separator"));o debería poder codificar "\" en lugar de decir "c:" como su directorio de archivos y podría funcionar. No es elegante, pero hizo el trabajo por mí en este proyecto.

Espero que ayude. Puede que no sea la solución correcta, pero al menos funcionó para mí. Estoy en JRE 1.6, Win 7. ¡Salud!

Respetuosamente,

@ Carpintero1010

Carpintero de código
fuente
0

Si las situaciones en las que falla implica ejecutarlo como otro usuario, y estás en Windows Vista / Windows 7, podría ser causado por VirtualStore, el mecanismo en el que Windows permite que un usuario sin privilegios "escriba" lugares en los que normalmente no puede. Sin embargo, los cambios se almacenan en "% USERPROFILE% \ AppData \ Local \ VirtualStore \", que son privados para cada cuenta de usuario.

Kjetil Joergensen
fuente
1
Me estoy ejecutando en windows xp x86
atsjoo
0

Cuando nada de arriba funcionó para mí, lo intenté

filePath = filePath.trim();

Esto limpiará su cuerda de cualquier carácter no deseado

Asim
fuente
0

Últimamente me encontré con este mismo problema. Lo que hice fue desinstalar Netbeans, eliminar la carpeta netbeans de la unidad C, archivos de programa, actualizar, programData, prácticamente en todas partes. Luego reinstale. Ahora está funcionando bien. No olvide hacer una copia de seguridad de la carpeta del proyecto netbeans antes de realizar las acciones anteriores.

Espero eso ayude.

Evaboy
fuente
0

Con algunos IDE (puede ser) y / o con algunos sistemas operativos (por ejemplo, ventana), de forma predeterminada no tienen acceso de escritura a los archivos. Entonces, si intentas hacer file.exists (), te mostrará falso. para solucionar este problema, haz lo siguiente

si su variable de referencia para Archivo es f, ejemplo: Archivo f = nuevo Archivo ("ruta");

así que para que funcione, seleccione f con el mouse y luego vaya al menú Buscar> Acceso de escritura> Espacio de trabajo. Ojalá funcione.

Gautam Anand
fuente
-2

Creo que deberías usar barra invertida en su lugar, así:

Archivo archivo = nuevo archivo ("C: \\ Usuario \\ utilidades \\ datos \\ someTextFile.txt"); (dos barras invertidas, no un error tipográfico)

Debería resolver el problema :)

Hussein Maziad
fuente
3
Creo que el problema está más relacionado con la ruta absoluta frente a la ruta relativa. Las barras son válidas en Java incluso para las rutas de Windows.
рüффп