que - ¿Cuál es la diferencia entre un recurso, URI, URL, ruta y archivo en Java?
uri java example (5)
Estoy totalmente confundido en este momento, principalmente debido a la terminología, supongo. ¿Puede alguien explicarme las diferencias o proporcionarme algunos enlaces a material a prueba de simulación? ¿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 nace principalmente de la evolución de Java como API y como plataforma a lo largo del tiempo. Para entender 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.
Recorreré los conceptos y cómo surgieron. Contestaré sus otras preguntas específicas después de eso, porque quizás tenga que referirme a algo en la primera parte.
¿Qué es un "recurso"?
Una pieza de datos abstracta y genérica que se puede ubicar y leer. En pocas palabras, Java usa esto para referirse a un "archivo" que puede no ser un archivo pero que representa una pieza de datos con nombre. No tiene una clase directa o representación de interfaz en Java , pero debido a sus propiedades (localizables, legibles) 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 hace una clara diferencia (teórica) entre un archivo (algo en el local sistema de archivos) y un recurso (algo que necesita leer).
Es por eso que la lectura de algo relativo a la aplicación (iconos, archivos de clase, etc.) se realiza a través de
ClassLoader.getResource
y no a través de la clase File.
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 .
java.io.File (java.io, 1.0)
Una representación abstracta de nombres de ruta de archivo y directorio.
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 File no necesita apuntar a algo local , solo algo que la plataforma de host entiende en el contexto del acceso a archivos, por ejemplo, una ruta UNC en Windows. Si monta un archivo ZIP como un sistema de archivos en su sistema operativo, File leerá bien las entradas que contiene.
java.net.URL (java.net, 1.0)
La URL de 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 un recurso, la URL representa ese recurso de la misma manera que la clase File representa un archivo en la plataforma host: como una cadena estructurada que apunta a un recurso. Además, la URL contiene un esquema que sugiere cómo llegar al recurso (con "archivo:" es "preguntar a la plataforma de host"), y permite apuntar a los 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 imaginó a principios de los años noventa.
java.net.URI (java.net, 1.4)
Representa una referencia de identificador uniforme de recursos (URI).
URI es una (leve) abstracción sobre URL. La diferencia entre URI y URL es conceptual y principalmente académica, pero URI está mejor definida 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 tiene la expectativa de ser resoluble , algo de lo que la aplicación podría desear un InputStream; un URI se trata más como una cosa abstracta que puede apuntar a algo resoluble (y generalmente lo hace), pero lo que significa y cómo alcanzarlo están más abiertos al contexto y la interpretación.
java.nio.file.Path (java.nio.file, 1.7)
Un objeto que puede usarse para ubicar un archivo en un sistema de archivos. Normalmente 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 forma parte de la API New IO File . Cuando File necesariamente apunta a un "archivo" tal como lo entiende la plataforma 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 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 clase de la aplicación, o realmente cualquier cosa que pueda representarse de manera significativa a través de la interfaz FileSystem y su controlador, FileSystemProvider. Trae el poder de "montar" sistemas de archivos en el contexto de una aplicación Java.
La plataforma host se representa a través del "sistema de archivos predeterminado";
cuando llama a
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, las cadenas de ruta y archivo)?
Improbable.
Si el archivo jar está en el sistema de archivos local, no debería tener un componente de consulta, por lo que
URL.getPath
y
URL.getFile
deberían devolver el mismo resultado.
Sin embargo, elija el que necesita: las URL de archivo no suelen tener componentes de consulta, pero 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 File 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, entonces File o Path las proporcionan.
No necesita Archivo si tiene acceso a Ruta. Sin embargo, algunas API antiguas pueden requerir Archivo.
(¿Y hay un objeto Resource?)
No, no hay
Hay muchas cosas nombradas así, pero no son un recurso en el sentido de
ClassLoader.getResource
.
Estoy viendo un fragmento de código Java en este momento, y toma una ruta como String y obtiene su URL usando
URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);
, luego llama a
String path = resource.getPath()
y finalmente ejecuta un
new File(path);
.
Ah, y también hay llamadas a
URL url = resource.toURI();
y
String file = resource.getFile()
.
Estoy totalmente confundido en este momento, principalmente debido a la terminología, supongo. ¿Puede alguien explicarme las diferencias o proporcionarme algunos enlaces a material a prueba de simulación? ¿Especialmente URI a URL y recurso a archivo ? Para mí, parece que deberían ser lo mismo, respectivamente ...
La diferencia entre
getFile()
y
getPath()
se explica aquí:
¿Cuál es la diferencia entre url.getFile () y getpath ()?
(Curiosamente, ambos parecen devolver cadenas, lo que probablemente agrega mucho a mi estado de ánimo ...)
Ahora, si tengo un localizador que hace referencia a una clase o paquete en un archivo jar, ¿diferirán esos dos (es decir, las cadenas de ruta y archivo)?
resource.toString()
le daría
jar:file:/C:/path/to/my.jar!/com/example/
, después de todo (tenga en cuenta el signo de exclamación).
¿La diferencia entre URI y URL en Java es que la primera no codifica espacios? Cf. Archivos, URI y URL que entran en conflicto en Java (Esta respuesta explica la diferencia conceptual general entre los dos términos bastante bien: los URI se identifican y las URL se ubican; )
Por último, y lo más importante,
¿por qué necesito el objeto
File
?
¿Por qué no es suficiente un recurso (
URL
)?
(¿Y hay un objeto Resource?)
Lo siento si esta pregunta es un poco desorganizada; solo refleja la confusión que tengo ... :)
Según tengo entendido, podría clasificarlos de la siguiente manera:
Basado en la web: URI y URL.
- URL: una URL es una ubicación definida en el interno (solo una dirección web normal, como .com)
- URI: Ever URL es un URI. Pero los URI también pueden contener cosas como "mailto:", por lo que también son, bueno, algo así como un "script" que yo diría.
Y local: recurso, ruta y archivos
- Recurso: Los recursos son archivos dentro de su jar. Se utilizan para cargar archivos de tarros / contenedores.
- Ruta: una ruta es básicamente una cadena. Pero viene con algunas funciones útiles para concatenar múltiples cadenas o agregar archivos a una cadena. Se asegura de que la ruta que está construyendo sea válida.
- Archivo: Esta es una referencia a un directorio o archivo. Se utiliza para modificar archivos, abrirlos, etc.
Sería más fácil si se fusionaran en una clase: son realmente confusos: D
Espero que esto te ayude :)
(Acabo de echar un vistazo a la documentación - mira docs.oracle.com)
Un archivo es una representación abstracta de una entidad en el sistema de archivos local.
Una ruta es generalmente una cadena que indica la ubicación de un archivo dentro de un sistema de archivos. Por lo general, no incluye el nombre del archivo. Entonces, c: / documents / mystuff / stuff.txt tendría una ruta con el valor de "C: / documents / mystuff" Obviamente, el formato de los nombres de archivos absolutos y las rutas variarían enormemente de un sistema de archivos a otro.
URL es un conjunto de URI con URL que generalmente representa recursos accesibles a través de http. No creo que haya una regla de ironclad sobre cuándo algo tiene que ser un URI frente a una URL. Los URI son cadenas en forma de "protocolo: // identificador de recursos" como bitcoin: // params, http://something.com?param=value . Las clases como URL generalmente envuelven la cadena y proporcionan métodos de utilidad que String no tendría ninguna razón para proporcionar.
No existe tal cosa como Recurso, al menos no en el sentido del que estás hablando. El hecho de que un método se llame getResource no significa que devuelva un objeto de tipo Resource.
En última instancia, la mejor manera de descubrir qué hacen los métodos de una Clase es crear una instancia de él en su código, llamar a los métodos y luego pasar al modo de depuración o enviar los resultados a System.out.
ACTUALIZACIÓN 2017-04-12 ¡ Comprueba la respuesta de JvR ya que contiene una explicación más exhaustiva y exacta!
Tenga en cuenta que no me considero 100% competente para responder, sin embargo, aquí hay algunos comentarios:
-
File
representa un archivo o directorio accesible a través del sistema de archivos -
recurso
es un
término genérico
para un objeto de datos que la aplicación puede cargar
- Por lo general, los recursos son archivos distribuidos con la aplicación / biblioteca y cargados a través del mecanismo de carga de clases (cuando residen en la ruta de clase)
-
URL#getPath
es getter en la parte de ruta de URL (protocol://host/path?query
) -
URL#getFile
segúnURL#getFile
devuelvepath+query
En Java,
URI
es solo una estructura de datos para manipular el identificador genérico en sí.
URL
por otro lado, es realmente un localizador de recursos y le ofrece funciones para leer realmente el recurso a través de
URLStreamHandler
s registrados.
Las URL pueden conducir a recursos del sistema de archivos y puede construir una URL para cada recurso del sistema de archivos mediante el uso del protocolo
file://
(de ahí la relación
URL
File
<->).
También tenga en cuenta que la
URL#getFile
no está relacionada con
java.io.File
.
¿Por qué necesito el objeto Archivo? ¿Por qué no es suficiente un recurso (URL)?
Es suficiente.
Solo si desea pasar el recurso a algún componente que pueda funcionar solo con archivos, debe obtener el
File
de él.
Sin embargo, no todas las URL de recursos se pueden convertir a
File
.
¿Y hay un objeto Recurso?
Desde el punto de vista de JRE, es solo un término. Algunos marcos le proporcionan dicha clase (por ejemplo, Spring''s Resource ).
share es agradable.
Como él dice, la palabra "archivo" tiene significados totalmente diferentes (prácticamente no relacionados) en
URL#getFile
vs
java.io.File
- puede ser parte de la confusión.
Solo para agregar:
-
Un recurso en Java es un concepto abstracto, una fuente de datos que se puede leer. La ubicación (o dirección) de un recurso está representada en Java por un objeto
URL
. -
Un recurso puede corresponder a un archivo normal en el sistema de archivos local (específicamente, cuando su
URL
comienza con elfile://
). Pero un recurso es más general (también puede ser algún archivo almacenado en un jar, o algunos datos para leer desde la red, o desde la memoria, o ...). Y también es más limitado, porque también se puede crear y escribir en unFile
(además de ser algo más que un archivo normal: un directorio, un enlace). -
Recuerde que en Java un objeto
File
realmente no representa "un archivo" sino la ubicación (el nombre completo, con la ruta) de un archivo. Entonces, un objetoFile
permite ubicar (y abrir) un archivo, ya que unaURL
permite acceder (y abrir) un recurso. (¡No hay una clase deResource
en Java para representar un recurso, pero tampoco hay una para representar un archivo! Una vez más: elFile
no es un archivo, es la ruta de un archivo).