Je regarde un morceau de code Java en ce moment, et il prend un chemin sous forme de chaîne et obtient son URL en utilisant URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);
, puis appelle String path = resource.getPath()
et enfin s'exécute new File(path);
.
Oh, et il y a aussi des appels vers URL url = resource.toURI();
et String file = resource.getFile()
.
Je suis totalement confus en ce moment - principalement à cause de la terminologie, je suppose. Quelqu'un peut-il s'il vous plaît me guider à travers les différences ou fournir quelques liens vers du matériel factice? Surtout URI vers URL et ressource vers fichier ? Pour moi, j'ai l'impression qu'ils devraient être la même chose, respectivement ...
La différence entre getFile()
et getPath()
est expliquée ici: Quelle est la différence entre url.getFile () et getpath ()? (Fait intéressant, ils semblent tous les deux renvoyer des chaînes, ce qui ajoute probablement beaucoup à mon état d'esprit ...)
Maintenant, si j'ai un localisateur qui fait référence à une classe ou à un package dans un fichier jar, ces deux (c'est-à-dire le chemin et les chaînes de fichiers) seront-ils différents?
resource.toString()
vous donnerait jar:file:/C:/path/to/my.jar!/com/example/
, après tout (notez le point d'exclamation).
La différence entre l' URI et l' URL en Java est-elle que le premier n'encode pas les espaces? Cf. Fichiers, URI et URL en conflit en Java (Cette réponse explique assez bien la différence conceptuelle générale entre les deux termes: les URI identifient et les URL localisent; )
Enfin - et surtout - pourquoi ai-je besoin d'un File
objet; pourquoi une Resource ( URL
) n'est-elle pas suffisante? (Et y a-t-il un objet Resource?)
Désolé si cette question est un peu désorganisée; cela reflète juste la confusion que j'ai ... :)
la source
Path
et FileSystem de NIO :)URL
est opaque - comme vous le montrez, c'est-àjar:file:
-dire une ressource dans une.jar
archive. IlFile
est très peu probable que cela aboutisse à quelque chose d'utile.Réponses:
MISE À JOUR 2017-04-12 Vérifiez la réponse de JvR car elle contient des explications plus exhaustives et exactes!
Veuillez noter que je ne me considère pas à 100% compétent pour répondre, mais voici néanmoins quelques commentaires:
File
représente un fichier ou un répertoire accessible via le système de fichiersURL#getPath
est getter sur la partie chemin de l'URL (protocol://host/path?query
)URL#getFile
selon les retours JavaDocpath+query
En Java, il
URI
s'agit simplement d'une structure de données pour manipuler l'identifiant générique lui-même.URL
d'autre part est vraiment un localisateur de ressources et vous offre des fonctionnalités pour lire réellement la ressource via desURLStreamHandler
s enregistrés .Les URL peuvent conduire à des ressources de système de fichiers et vous pouvez construire une URL pour chaque ressource de système de fichiers en utilisant le
file://
protocole (d'où la relationFile
<->URL
).Sachez également que cela
URL#getFile
n'a aucun rapport avecjava.io.File
.C'est assez. Ce n'est que si vous souhaitez transmettre la ressource à un composant qui ne peut fonctionner qu'avec des fichiers, vous devez en tirer
File
. Cependant, toutes les URL de ressources ne peuvent pas être converties enFile
s.Du point de vue JRE, ce n'est qu'un terme. Certains frameworks vous fournissent une telle classe (par exemple Spring's Resource ).
la source
java.nio.file.Path
, qui est essentiellement un remplacement (Java 7+) pourjava.io.File
, car cette dernière API était apparemment mal pensée au début de Java.La terminologie est déroutante et parfois déroutante, et est principalement née de l'évolution de Java en tant qu'API et en tant que plate-forme au fil du temps. Pour comprendre comment ces termes ont fini par signifier ce qu'ils font, il est important de reconnaître deux choses qui influencent la conception de Java:
Je vais parcourir les concepts et comment ils sont nés. Je répondrai à vos autres questions précises après cela, car je devrai peut-être faire référence à quelque chose dans la première partie.
Qu'est-ce qu'une «ressource»?
Un élément de données abstrait et générique qui peut être localisé et lu. En clair, Java l'utilise pour désigner un «fichier» qui n'est peut-être pas un fichier mais qui représente une donnée nommée. Il n'a pas de représentation directe de classe ou d'interface en Java , mais en raison de ses propriétés (localisables, lisibles), il est souvent représenté par une URL.
Parce que l'un des premiers objectifs de conception de Java était d'être exécuté à l'intérieur d'un navigateur, en tant qu'application sandbox (applets!) Avec des droits / privilèges / habilitation de sécurité très limités, Java fait une différence claire (théorique) entre un fichier (quelque chose sur le système de fichiers) et une ressource (quelque chose qu'il doit lire). C'est pourquoi la lecture de quelque chose relatif à l'application (icônes, fichiers de classe, etc.) se fait via
ClassLoader.getResource
et non via la classe File.Malheureusement, parce que "ressource" est également un terme générique utile en dehors de cette interprétation, il est également utilisé pour nommer des choses très spécifiques (par exemple, classe ResourceBundle , UIResource , Resource ) qui ne sont pas, dans ce sens, une ressource.
Les principales classes représentant (un chemin vers) une ressource sont java.nio.file.Path , java.io.File , java.net.URI et java.net.URL .
Fichier (java.io, 1.0)
La classe File représente une ressource accessible via le système de fichiers natif de la plateforme . Il ne contient que le nom du fichier, il s'agit donc plutôt d'un chemin (voir plus loin) que la plateforme hôte interprète selon ses propres paramètres, règles et syntaxe.
Notez que File n'a pas besoin de pointer vers quelque chose de local , juste quelque chose que la plate-forme hôte comprend dans le contexte de l'accès aux fichiers, par exemple un chemin UNC dans Windows. Si vous montez un fichier ZIP en tant que système de fichiers dans votre système d'exploitation, File lira très bien ses entrées contenues.
URL (java.net, 1.0)
En tandem avec le concept de ressource, l'URL représente cette ressource de la même manière que la classe File représente un fichier dans la plate-forme hôte: sous la forme d' une chaîne structurée qui pointe vers une ressource. URL contient en plus un schéma qui indique comment atteindre la ressource (avec "file:" étant "demander à la plate-forme hôte"), et permet ainsi de pointer vers les ressources via HTTP, FTP, dans un JAR, etc.
Malheureusement, les URL ont leur propre syntaxe et terminologie, y compris l'utilisation de «fichier» et «chemin». Dans le cas où l'URL est une URL de fichier, URL.getFile renverra une chaîne identique à la chaîne de chemin du fichier référencé.
Class.getResource
renvoie une URL: il est plus flexible que le renvoi de File, et il a répondu aux besoins du système comme imaginé au début des années 1990.URI (java.net, 1.4)
L'URI est une (légère) abstraction sur l'URL. La différence entre l'URI et l'URL est conceptuelle et principalement académique, mais l'URI est mieux définie dans un sens formel et couvre un plus large éventail de cas d'utilisation. Parce qu'URL et URI sont / n'étaient pas la même chose, une nouvelle classe a été introduite pour les représenter, avec les méthodes URI.toURL et URL.toURI pour se déplacer entre l'une et l'autre.
En Java, la principale différence entre l'URL et l'URI est qu'une URL est censée être résoluble , ce dont l'application peut souhaiter un InputStream; un URI est traité plus comme un thingamajig abstrait qui pourrait pointer vers quelque chose de résoluble (et le fait généralement), mais ce que cela signifie et comment l'atteindre sont plus ouverts au contexte et à l'interprétation.
Chemin (java.nio.file, 1.7)
La nouvelle API de fichier, iconifiée dans l'interface Path, permet une flexibilité beaucoup plus grande que celle que la classe File pourrait offrir. L'interface Path est une abstraction de la classe File et fait partie de l' API New IO File . Où File pointe nécessairement vers un "fichier" tel que compris par la plateforme hôte, Path est plus générique: il représente un fichier (ressource) dans un système de fichiers arbitraire .
Path supprime la dépendance au concept de fichier de la plate-forme hôte. Il peut s'agir d'une entrée dans un fichier ZIP, d'un fichier accessible via FTP ou SSH-FS, une représentation multi-racine du chemin de classe de l'application, ou vraiment tout ce qui peut être représenté de manière significative via l'interface FileSystem et son pilote, FileSystemProvider. Il apporte la puissance de "monter" des systèmes de fichiers dans le contexte d'une application Java.
La plate-forme hôte est représentée par le "système de fichiers par défaut"; lorsque vous appelez
File.toPath
, vous obtenez un chemin sur le système de fichiers par défaut.Improbable. Si le fichier jar est sur le système de fichiers local, vous ne devriez pas avoir un composant de requête, donc
URL.getPath
etURL.getFile
doit retourner le même résultat. Cependant, choisissez celui dont vous avez besoin: les URL de fichiers peuvent généralement ne pas avoir de composants de requête, mais je pourrais certainement en ajouter un de toute façon.L'URL peut ne pas être suffisante car File vous donne accès à des données de gestion telles que les autorisations (lisibles, inscriptibles, exécutables), le type de fichier (suis-je un répertoire?), Et la possibilité de rechercher et de manipuler le système de fichiers local. Si ce sont des fonctionnalités dont vous avez besoin, File ou Path les fournit.
Vous n'avez pas besoin de File si vous avez accès à Path. Cependant, certaines API plus anciennes peuvent nécessiter un fichier.
Non, il n'y en a pas. Il y a beaucoup de choses nommées comme ça, mais elles ne sont pas une ressource au sens de
ClassLoader.getResource
.la source
La réponse de Pavel Horal est sympa.
Comme il le dit, le mot «fichier» a des significations totalement différentes (pratiquement sans rapport) dans
URL#getFile
vsjava.io.File
- peut-être que cela fait partie de la confusion.Juste pour ajouter:
Une ressource en Java est un concept abstrait, une source de données qui peuvent être lues. L'emplacement (ou l'adresse) d'une ressource est représenté en Java par un
URL
objet.Une ressource peut correspondre à un fichier normal dans le système de fichiers local (en particulier, quand il
URL
commence parfile://
). Mais une ressource est plus générale (il peut s'agir aussi d'un fichier stocké dans un jar, ou de certaines données à lire depuis le réseau, ou depuis la mémoire, ou ...). Et c'est aussi plus limité, car unFile
(en plus d'être autre chose qu'un fichier normal: un répertoire, un lien) peut également être créé et écrit.Rappelez-vous qu'en Java, un
File
objet ne représente pas vraiment "un fichier" mais l'emplacement (le nom complet, avec chemin) d'un fichier. Ainsi, unFile
objet vous permet de localiser (et d'ouvrir) un fichier, tout comme unURL
vous permet d'accéder (et d'ouvrir) une ressource. (Il n'y a pas deResource
classe en Java pour représenter une ressource, mais il n'y en a pas non plus pour représenter un fichier! Encore une fois: ceFile
n'est pas un fichier, c'est le chemin d'un fichier).la source
Si je les comprends bien, vous pouvez les classer comme suit:
Basé sur le Web: URI et URL.
Et local: ressource, chemin et fichiers
Ce serait plus facile si elles étaient fusionnées en une seule classe - elles sont vraiment déroutantes: D
J'espère que ceci vous aide :)
(Je viens de jeter un œil à la documentation - regardez docs.oracle.com)
la source
Un fichier est une représentation abstraite d'une entité dans le système de fichiers local.
Un chemin est généralement une chaîne indiquant l'emplacement d'un fichier dans un système de fichiers. Il n'inclut généralement pas le nom de fichier. Donc c: \ documents \ mystuff \ stuff.txt aurait un chemin avec la valeur de "C: \ documents \ mystuff" Evidemment, le format des noms de fichiers et des chemins absolus varierait énormément d'un système de fichiers à un autre.
URL est un sous-ensemble d'URI avec une URL représentant généralement des ressources accessibles via http. Je ne pense pas qu'il y ait une sorte de règle absolue sur le moment où quelque chose doit être un URI par rapport à une URL. Les URI sont des chaînes sous la forme "protocol: // resource-identifier" comme bitcoin: // params, http://something.com?param=value . Les classes comme URL enveloppent généralement la chaîne et fournissent des méthodes utilitaires que String n'aurait aucune raison de fournir.
Rien de tel que Resource, du moins pas dans le sens dont vous parlez. Ce n'est pas parce qu'une méthode est nommée getResource qu'elle renvoie un objet de type Resource.
En fin de compte, la meilleure façon de comprendre ce que font les méthodes d'une classe est de créer une instance de celle-ci dans votre code, d'appeler les méthodes, puis de passer en mode débogage ou d'envoyer les résultats à System.out.
la source