Pregunta

Cuando ejecuto una aplicación Java que debería leerse desde un archivo en Eclipse, aparece un java.io.FileNotFoundException, aunque el archivo esté en el directorio correcto.Puedo compilar y ejecutar la aplicación desde la línea de comandos perfectamente;el problema sólo ocurre en Eclipse, con más de un proyecto y aplicación.¿Hay alguna configuración que deba cambiar en las configuraciones de ejecución o en las rutas de compilación para que encuentre el archivo correctamente?

¿Fue útil?

Solución

Es muy probable que la aplicación está utilizando una ruta relativa al problema. Como dice @BalusC, rutas relativas pueden ser problemáticos. Pero En mi opinión, va demasiado lejos cuando dice "[N] o debe no utilizar rutas relativas en materia java.io" .

Cuando una aplicación abre un archivo usando (por ejemplo) el constructor FileInputStream(File), rutas relativas se resuelven en relación con el "directorio actual" en un proceso descrito como sigue en el Javadoc para File.getAbsolutePath() .

[...] De lo contrario esta ruta se resuelve de una manera dependiente del sistema. En sistemas UNIX, un nombre de ruta relativa se hizo absoluta resolviendo contra el directorio de usuario actual. En los sistemas Microsoft Windows, un nombre de ruta relativa se hizo absoluta mediante la resolución contra el directorio actual de la unidad denominada por el nombre de ruta, si los hubiere; Si no es así, se resuelve contra el directorio del usuario actual.

Así que de inmediato, vemos que la noción de "directorio actual" tiene diferentes matices sobre plataformas Windows y UNIX. La segunda cuestión es que en Java puro no se puede encontrar definitivamente lo que el directorio actual es, y que sin duda no se puede cambiar para la JVM actual utilizando Java puro. (Cuando se inicia la JVM, la propiedad del sistema "user.dir" se establece en el directorio actual, pero no hay nada que una aplicación cambie la propiedad lo que no puede confiar exclusivamente en él. Por otra parte, el cambio de "user.dir" sólo cambia la forma en que la ruta vacía se resuelve, no las rutas relativas en general.)

Entonces, qué debe hacer al respecto?

  • Una opción es utilizar rutas absolutas para referirse a los archivos. Esta es fiable en (casi) todos los casos, pero utilizando rutas absolutas puede ser problemático si el usuario tiene que introducir el nombre de ruta, o si es necesario para evitar cableados (o configurado) rutas absolutas.

  • Una segunda opción es utilizar rutas relativas de ruta de clases y localizar los archivos relativos al directorio de instalación de la aplicación. Estos trabajos si eso es lo que hay que hacer, pero presenta un problema si usted necesita para pasar un File a algún método de biblioteca. También no ayuda si usted está tratando de encontrar preferencias de la aplicación del usuario. (En general, poniendo las preferencias del usuario en el directorio de instalación es un error ...)

  • Una tercera opción es nombrar un archivo con relación a algún directorio absoluta que reciba de otro lugar; p.ej. new File(System.getProperty("home.dir"), "foo/bar");.

  • La última opción es utilizar rutas relativas, y se supone que el usuario sepa lo que el directorio actual. Para muchas aplicaciones que el usuario ejecuta desde la línea de comandos, esta es la solución correcta.

En el caso particular de Eclipse, hay una solución simple. Ir a la "configuración de ejecución" que está utilizando para iniciar la aplicación, abra la pestaña "argumentos", y haga clic en el botón de opción "Otros". A continuación, introduzca una ruta absoluta como el directorio de trabajo para la aplicación iniciada. Cuando se inicia el niño JVM, que tendrá el directorio de trabajo especificado como su directorio actual.

Otros consejos

Otra opción es simplemente averiguar qué directorio de los puntos de "ruta actual" en su entorno - sea lo que sea. Una vez que averiguar, puede elegir su solución de allí. Tal vez esto es utilizar una ruta relativa apropiada de la ubicación del archivo o la ubicación del archivo.

    File testFile = new File("");
    String currentPath = testFile.getAbsolutePath();
    System.out.println("current path is: " + currentPath);

Cuando crea una aplicación Java predeterminada en Eclipse, obtiene esta estructura de directorio:

./Nombre del proyecto/ - directorio raíz
./NombreProyecto/bin/ - directorio de salida, que contiene archivos .class
./NombreProyecto/src/ - directorio fuente, que contiene archivos .java

Si su aplicación solicita "./data.txt", lo buscará en relación con el directorio raíz.Este es el "directorio de trabajo" y se puede configurar en la pestaña de argumentos según la respuesta anterior de Martin.

¿Dices que funciona desde la línea de comando?Es probable que esto se deba a que estás dentro de las carpetas bin o src cuando ejecutas el binario de Java.El directorio de trabajo en este caso es cualquier directorio dentro del cual se encuentre actualmente el símbolo del sistema.Si, por ejemplo, ingresa al directorio /src/, digamos javac *.java luego ejecute los archivos desde allí, buscará "./data.txt" dentro del directorio /src/.Si ingresa al directorio /bin/ y ejecuta su aplicación desde allí, buscará el archivo relativo al directorio /bin/.

debe no utilizar rutas relativas en materia java.io. El camino pasaría a depender del directorio de trabajo actual, que depende de la forma cómo se inició la aplicación y por lo tanto no es por sí mismo en todos los ambientes. Esta es incontrolable desde el interior de la aplicación Java. problemas para la portabilidad! Siempre utilice rutas absolutas. Así, por ejemplo, c:/path/to/file.ext o /path/to/file.ext (con la barra inicial) para UNIX y consortes (o incluso Windows cuando la letra de disco es irrelevante).

Siempre que desea enviar algunos archivos junto con su solicitud, una práctica común consiste en colocarlos en el ruta de clase también. De esta manera sólo se puede utilizar ClassLoader#getResource() para obtener su ubicación. Devuelve un URL . Puede usar URL#toURI() o URL#getPath() y pasarlo al constructor del java.io.File y luego usarlo aún más la forma habitual.

En su proyecto de Eclipse, la carpeta src (donde su fuente de Java va) es básicamente la raíz de la ruta de clases. Además, por supuesto también abarca todos los demás proyectos y carpetas (externos) que se toman en el proyecto de Build Path .

Si se asume que ha colocado el archivo en particular en el root de la ruta de clases:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("file.ext");
File file = new File(url.getPath());
FileInputStream input = new FileInputStream(file);
// ...

Se puede incluso utilizar ClassLoader#getResourceAsStream() para obtener directamente una InputStream :

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("file.ext");
// ...

Si se coloca dentro de un paquete, entonces usted puede simplemente utilizar los nombres de las rutas habituales:

URL url = classLoader.getResource("com/example/file.ext");
// ...

o

InputStream input = classLoader.getResourceAsStream("com/example/file.ext");
// ...

Yo estaba teniendo un problema similar, coloqué mis archivos en una carpeta cobolcopybooks nombrados dentro de la carpeta src y ha intentado acceder a ellos dentro de mi proyecto usando classloader.getResource ( "cobolcopybooks / demostud.cob") pero yo estaba recibiendo excepción de puntero nulo, lo intenté varias veces por la limpieza y la construcción de los espacios de trabajo después de varios intentos fallidos me di cuenta que no era refrescante, el proyecto para permitir que los archivos que se construyen junto con el proyecto. es decir estos archivos deben ser visibles, junto con otros archivos de clase en tiempo de ejecución como el directorio raíz será directorio bin y se está en busca de esos archivos allí.

Assuming the user does not enter the full file path to the file and enter something like "myfilenameonly". File file = new File(".", args[0]) is necessary in this case to locate the file (paying attention to the first argument passed).

All platforms: File.getParent() does not return the parent directory, it should return ".." or the name of the parent directory in a file-system specific way.

If you create the File "myfilenameonly" without specifying the full path to the directory where it is located, the File.getParent(), for example, will return null.

See further: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=1228537

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top