Estoy totalmente confundido en este momento, sobre todo por la terminología, supongo. ¿Alguien puede explicarme las diferencias o proporcionar algunos enlaces a material a prueba de falsificaciones? ¿Especialmente URI a URL y recurso a archivo? Para mí, parece que deberían ser lo mismo, respectivamente ...
La terminología es confusa y a veces confusa, y en su mayoría nace de la evolución de Java como API y como plataforma a lo largo del tiempo. Para comprender cómo estos términos llegaron a significar lo que hacen, es importante reconocer dos cosas que influyen en el diseño de Java:
- Compatibilidad al revés. Las aplicaciones antiguas deberían ejecutarse en instalaciones más nuevas, idealmente sin modificaciones. Esto significa que una API antigua (con sus nombres y terminología) debe mantenerse en todas las versiones más nuevas.
- Multiplataforma. La API debe proporcionar una abstracción utilizable de su plataforma subyacente, ya sea un sistema operativo o un navegador.
Analizaré los conceptos y cómo surgieron. Responderé a sus otras preguntas específicas después de eso, porque es posible que tenga que referirme a algo en la primera parte.
¿Qué es un "recurso"?
Un dato abstracto y genérico que se puede localizar y leer. En términos generales, Java usa esto para referirse a un "archivo" que puede no ser un archivo pero que representa un dato con nombre. No tiene una clase directa o una representación de interfaz en Java , pero debido a sus propiedades (localizable, legible) a menudo se representa mediante una URL.
Debido a que uno de los primeros objetivos de diseño de Java era ejecutarse dentro de un navegador, como una aplicación de espacio aislado (¡applets!) Con derechos / privilegios / autorización de seguridad muy limitados, Java marca una diferencia clara (teórica) entre un archivo (algo en el local sistema de archivos) y un recurso (algo que necesita leer). Esta es la razón por la que leer algo relativo a la aplicación (iconos, archivos de clase, etc.) se realiza a ClassLoader.getResourcetravés de la clase File y no a través de ella.
Desafortunadamente, debido a que "recurso" también es un término genérico útil fuera de esta interpretación, también se usa para nombrar cosas muy específicas (por ejemplo, clase ResourceBundle , UIResource , Resource ) que no son, en este sentido, un recurso.
Las clases principales que representan (una ruta a) un recurso son java.nio.file.Path , java.io.File , java.net.URI y java.net.URL .
Archivo (java.io, 1.0)
Una representación abstracta de nombres de rutas de archivos y directorios.
La clase File representa un recurso al que se puede acceder a través del sistema de archivos nativo de la plataforma . Contiene solo el nombre del archivo, por lo que en realidad es más una ruta (ver más adelante) que la plataforma host interpreta de acuerdo con su propia configuración, reglas y sintaxis.
Tenga en cuenta que el archivo no necesita apuntar a algo local , solo algo que la plataforma de host entiende en el contexto del acceso al archivo, por ejemplo, una ruta UNC en Windows. Si monta un archivo ZIP como un sistema de archivos en su sistema operativo, File leerá sus entradas contenidas sin problemas.
URL (java.net, 1.0)
La URL de la clase representa un localizador uniforme de recursos, un puntero a un "recurso" en la World Wide Web. Un recurso puede ser algo tan simple como un archivo o un directorio, o puede ser una referencia a un objeto más complicado, como una consulta a una base de datos o un motor de búsqueda.
Junto con el concepto de recurso, la URL representa ese recurso de la misma manera que la clase File representa un archivo en la plataforma de host: como una cadena estructurada que apunta a un recurso. La URL además contiene un esquema que sugiere cómo llegar al recurso (con "archivo:" siendo "preguntar a la plataforma de host"), y así permite apuntar a recursos a través de HTTP, FTP, dentro de un JAR y otras cosas.
Desafortunadamente, las URL vienen con su propia sintaxis y terminología, incluido el uso de "archivo" y "ruta". En caso de que la URL sea una URL de archivo, URL.getFile devolverá una cadena idéntica a la cadena de ruta del archivo referenciado.
Class.getResource devuelve una URL: es más flexible que devolver un archivo, y ha respondido a las necesidades del sistema como se imaginaba a principios de la década de 1990.
URI (java.net, 1.4)
Representa una referencia de identificador uniforme de recursos (URI).
URI es una abstracción (leve) sobre URL. La diferencia entre URI y URL es conceptual y principalmente académica, pero URI se define mejor en un sentido formal y cubre una gama más amplia de casos de uso. Debido a que URL y URI son / no eran lo mismo, se introdujo una nueva clase para representarlos, con los métodos URI.toURL y URL.toURI para moverse entre uno y otro.
En Java, la principal diferencia entre URL y URI es que una URL conlleva la expectativa de poder resolverse , algo de lo que la aplicación podría querer un InputStream; un URI se trata más como una cosa abstracta que puede apuntar a algo que se puede resolver (y generalmente lo hace), pero lo que significa y cómo llegar a él está más abierto al contexto y la interpretación.
Ruta (java.nio.file, 1.7)
Objeto que puede usarse para ubicar un archivo en un sistema de archivos. Por lo general, representará una ruta de archivo dependiente del sistema.
La nueva API de archivo, iconificada en la interfaz Path, permite una flexibilidad mucho mayor que la que podría ofrecer la clase File. La interfaz Path es una abstracción de la clase File y es parte de la API New IO File . Donde Archivo necesariamente apunta a un "archivo" como lo entiende la plataforma de host, Path es más genérico: representa un archivo (recurso) en un sistema de archivos arbitrario .
Path elimina la dependencia del concepto de archivo de la plataforma de host. Podría ser una entrada en un archivo ZIP, un archivo accesible a través de FTP o SSH-FS, una representación de múltiples raíces de la ruta de clases de la aplicación, o realmente cualquier cosa que se pueda representar de manera significativa a través de la interfaz FileSystem y su controlador, FileSystemProvider. Aporta el poder de "montar" sistemas de archivos en el contexto de una aplicación Java.
La plataforma de host se representa a través del "sistema de archivos predeterminado"; cuando llama File.toPath, obtiene una ruta en el sistema de archivos predeterminado.
Ahora, si tengo un localizador que hace referencia a una clase o paquete en un archivo jar, ¿diferirán esos dos (es decir, la ruta y las cadenas de archivo)?
Improbable. Si el archivo JAR está en el sistema de archivos local, no debe tener un componente de consulta, por lo que URL.getPathy URL.getFiledebe devolver el mismo resultado. Sin embargo, elija el que necesita: las URL de archivo pueden no tener normalmente componentes de consulta, pero seguro que podría agregar uno de todos modos.
Por último, y lo más importante, ¿por qué necesito el objeto File; ¿Por qué no es suficiente un recurso (URL)?
Es posible que la URL no sea suficiente porque Archivo le brinda acceso a datos de mantenimiento como permisos (legibles, de escritura, ejecutables), tipo de archivo (¿soy un directorio?) Y la capacidad de buscar y manipular el sistema de archivos local. Si estas son características que necesita, File o Path se las proporcionan.
No necesita Archivo si tiene acceso a Ruta. Sin embargo, algunas API más antiguas pueden requerir Archivo.
(¿Y hay un objeto de recurso?)
No, no lo hay. Hay muchas cosas nombradas así, pero no son un recurso en el sentido de ClassLoader.getResource.
Pathy FileSystem de NIO :)