Enviar respuesta 
 
Calificación:
  • 1 votos - 5 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Rutas Relativas en File()
jesusgaviria Sin conexión
ingeniero de software senior
***

Mensajes: 51
Registro en: Mar 2011
Reputación: 0
Mensaje: #1
Rutas Relativas en File()
No se si este problema tenga que estar en BD, pero lo estoy teniendo al llenar la BD...

el File(String Path) no acepta rutas relativas?, he tratado y tratado y nada que puedo, de hecho el ejemplo en que el vi esto, el de guardar una imagen en la base de datos usa ruta absoluta.

En esta Carpeta es donde estoy al correr el .java:
gsusgp@gsusgp:~/workspace/BD2/src/BD$

Si le hago
gsusgp@gsusgp:~/workspace/BD2/src/BD$ cd ../Imagenes/Terreno/

y aquí están mis imágenes.
gsusgp@gsusgp:~/workspace/BD2/src/Imagenes/Terreno$

así que el File() debería verse algo así (o al menos es lo lógico)
File("../Imagenes/Terreno/jardin.gif")
o en el peor de los casos File("./../Imagenes/Terreno/jardin.gif"

pero nada, tengo que meter la ruta absoluta Confused...
File("/home/gsusgp/workspace/BD2/src/Imagenes/Terreno/pastoseco.gif")
y así si lo agarra,
AYUDA?
05-07-2011 10:47 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #2
RE: Rutas Relativas en File()
El asunto de las rutas de archivos es un pequeño dolor de cabeza, y en java la cosa tiene su dosis extra de locura.

En primer lugar: File si acepta rutas relativas, pero el asunto está en entender ¿relativas a que?. Cuando se especifica una ruta relativa, ésta siempre es relativa al CWD, es decir al Current Working Directory (El directorio actual de trabajo), que por ejemplo, en linux es el mismo directorio desde el que se corre el programa.

Es decir, en Java no puedes especificar las rutas relativas al archivo .java donde estas usando la clase File, sino la ruta relativa al directorio de trabajo. En el caso de eclipse, cuando corres un programa, el directorio de trabajo es la raiz del proyecto.

Si por ejemplo tienes:

Código:
/
|-home
  |-dmi
    |-workspace
      |-MiProyecto
        |-src
        | |-com
        |   |-paquete
        |   | |-MiClase.java <--- Aquí se hace new File(...)
        |   | |-otraimagen.png
        |   |-otropaquete
        |     |-imagen1.jpg
        |-imagenes
          |-imagen2.jpg

Y tratas de cargar las imagenes imagen1.jpg e imagen2.jpg usando File en MiClase.java, si asumes que el programa se está corriendo desde eclipse, entonces puedes hacer:

Código:
new File("imagenes/imagen2.jpg") // <-- Esto debería funcionar
new File("src/com/otropaquete/imagen1.jpg") // <-- Esto también debería funcionar
new File("src/com/paquete/otraimagen.png") // <-- Esto también debería funcionar

Evidentemente, si especificas rutas relativas desde MiClase.java, como por ejemplo:

Código:
new File("../../../imagenes/imagen2.jpg") // <-- Nada de esto funciona
new File("../otropaquete/imagen1.jpg") // <-- Nada de esto funciona
new File("otraimagen.png") // <-- Nada de esto funciona

Porque como te digo, la ruta se toma relativa al CWD y no a la clase en Java desde la que la usas.

Hasta aquí creo que esto te resuelve tu problema siempre que corras el programa desde eclipse (me refiero a que el programa tenga un main). No se sinceramente de memoria si la cosa te va a funcionar desde Echo, es decir, desde un servidor WEB, y esto se debe a que no estoy claro en cual va a ser el CWD (recuerda que te estoy diciendo todo esto de memoria, es decir, si validar mucho con el código). En general, las cosas se complican cuando cargas recursos y no sabes de antemano cual va a ser el CWD o donde van a estar las imágenes.

En java lo que se suele hacer es que uno empaqueta las imágenes junto con los .class, es decir, dentro de los mismos paquetes del programa. Lo que quiero decir es que en el ejemplo anterior, imagen1.jpg es una imagen que está "dentro" de los mismos paquetes del programa (porque está debajo del directorio src), mientras que imagen2.jpg no lo es, porque si bien está dentro del proyecto, está fuera del src.

Ahora bien, aquí se da algo interesante. Java tiene un concepto llamado CLASSPATH, que es muy parecido al PATH de UNIX (espero que sepan lo que es eso porque no lo voy a explicar), pero que en lugar de servir de "ruta" de búsqueda para binarios/programas sirve como ruta para buscar paquetes y clases. Lo que trato de decir, es que si vas a correr un programa como MiClase (recordar que con el paquete el nombre completo de esta clase es "com.paquete.MiClase") en nuestro ejemplo, en algún lugar del CLASSPATH tiene que estar especificada una ruta (directorio) desde el que "salga" una serie de subdirectorios com/paquete que concuerden con el nombre del paquete y que en este último directorio "paquete" se encuentre un archivo "MiClase.class" (que es el compilado del .java). Si lo ves desde este punto de vista, entonces uno puede usar el mismo principio para localizar imágenes, es decir, uno puede decir que la "ruta relativa" de imagen1.jpg es "com/otropaquete/imagen1.jpg"

Entender el CLASSPATH es algo importante si se quiere avanzar en un determinado momento en Java, algunas referencias:

http://en.wikipedia.org/wiki/Classpath_%28Java%29
http://javarevisited.blogspot.com/2011/0...-java.html

Aunque si te soy franco no consigo un tutorial realmente decente en español (aunque debe existir).

En fin, volviendo a las imágenes, una vez que entendemos lo del CLASSPATH, uno puede cargar las imagenes usando rutas relativas y/o absolutas. Realmente no se bien como es el asunto con File, pero en general, cuando uno carga un recurso del CLASSPATH normalmente uno quiere un objeto de tipo InputStream, que se puede obtener (si estas en MiClase) de esta forma:

Código:
// ESTO NO VA A FUNCIONAR, PORQUE EN PRINCIPIO imagenes/ NO ESTA EN EL CLASSPATH
InputStream is = ClassLoader.getSystemResource("imagenes/imagen2.jpg");

// Notar que a diferencia del ejemplo anterior no ponemos el "src" antes del com/otropaquete
// esto se debe a que no está haciendo una búsqueda relativa al CWD sino relativa al
// CLASSPATH, y en este caso "src" está en el classpath (o debería desde eclipse).
InputStream is = ClassLoader.getSystemResource("com/otropaquete/imagen1.jpg");

InputStream is = ClassLoader.getSystemResource("com/paquete/otraimagen.png");

En el caso anterior se están especificando rutas "relativas" con respecto a alguno de los directorios del CLASSPATH. También se puede hacer con rutas relativas respecto a la ubicación de una clase, lo que se hace como:

Código:
// ESTO NO VA A FUNCIONAR NI SOÑARLO
InputStream is = getClass().getResource("../../../imagenes/imagen2.jpg");

// Esto funciona directo, porque es relativo a la clase actual, es decir, está buscando
// la imagen en el mismo paquete de la clase que retorne getClass()
InputStream is = getClass().getResource("otraimagen.png");

// Esto si les soy sincero no lo he probado así que no estoy muy seguro si funciona,
// sería bueno averiguarlo.
InputStream is = getClass().getResource("../otropaquete/imagen1.jpg");

Noten que estoy asumiendo que el código anterior se ejecuta dentro de alguna función de "MiClase", por lo que getClass() retorna la instancia de tipo "Class" asociada a MiClase.

Creo que si bien apenas he arañado la superficie de todo el asunto, y debo decir que la he arañado escribiendo de memoria, muy rápido y de forma un tanto descuidada, espero que al menos sea suficiente para aclarar un poco el asunto y darles los punteros para que sigan averiguando un poco más al respecto.

Cualquier duda o referencia interesante que consigan me avisan,
Saludos,
Demián

[Imagen: dmi-1.jpg]
07-07-2011 06:20 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
Enviar respuesta 


Salto de foro:


Usuario(s) navegando en este tema: 3 invitado(s)