Quelle est la différence entre une ressource, un URI, une URL, un chemin et un fichier en Java?

Je regarde un morceau de code Java en ce moment, et il prend un chemin en tant que chaîne et obtient son URL en utilisant URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsSsortingng); , puis appelle Ssortingng path = resource.getPath() et exécute enfin le new File(path); .

Oh, et il y a aussi des appels à l’ URL url = resource.toURI(); et Ssortingng file = resource.getFile() .

Je suis totalement confus en ce moment – principalement à cause de la terminologie, je suppose. Est-ce que quelqu’un peut me guider à travers les différences ou fournir quelques liens vers du matériel à l’épreuve des mannequins? Surtout l’URI à l’URL et la ressource au fichier ? Pour moi, on a 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, les deux semblent renvoyer des chaînes, ce qui ajoute probablement beaucoup à mon état d’esprit …)

Maintenant, si j’ai un localisateur qui référence une classe ou un package dans un fichier jar, est-ce que ces deux éléments (c.-à-d. Les chaînes d’un fichier) seront différents?

resource.toSsortingng() vous donnerait jar:file:/C:/path/to/my.jar!/com/example/ , après tout (notez le point d’exclamation).

Est-ce que la différence entre URI et URL dans Java est que la première ne code pas les espaces? Cf. Fichiers, URI et URL en conflit dans Java (Cette réponse explique assez bien la différence conceptuelle générale entre les deux termes: les URI identifient et les URL sont localisées; )

Enfin et surtout, pourquoi ai-je besoin d’un object File ? pourquoi une ressource ( URL ) n’est-elle pas suffisante? (Et y a-t-il un object Ressource?)

Désolé si cette question est un peu désorganisée; cela reflète simplement la confusion que j’ai … 🙂

MISE À JOUR 2017-04-12 Vérifiez la réponse de JvR car elle contient une explication plus exhaustive et exacte!


Veuillez noter que je ne me considère pas 100% compétent pour répondre, mais néanmoins, voici quelques commentaires:

  • File représente un fichier ou un répertoire accessible via le système de fichiers
  • ressource est un terme générique pour un object de données qui peut être chargé par l’application
    • les ressources sont généralement des fichiers dissortingbués avec l’application / la bibliothèque et chargés via le mécanisme de chargement de classe (lorsqu’ils résident sur le chemin de classe)
  • URL#getPath est un getter sur la partie chemin de l’URL ( protocol://host/path?query )
  • URL#getFile selon JavaDoc renvoie le path+query

En Java, l’ URI n’est qu’une structure de données permettant de manipuler l’identificateur générique lui-même.

URL en revanche est en réalité un localisateur de ressources et vous propose des fonctionnalités permettant de lire la ressource via des URLStreamHandler enregistrés.

Les URL peuvent générer des ressources de système de fichiers et vous pouvez créer une URL pour chaque ressource de système de file:// aide du file:// protocol (d’où la relation File < -> URL ).

URL#getFile également que cette URL#getFile n’est pas liée à java.io.File .


Pourquoi ai-je besoin d’un object File? pourquoi une ressource (URL) n’est-elle pas suffisante?

C’est assez. Seulement si vous voulez transmettre la ressource à un composant qui ne peut fonctionner qu’avec des fichiers, vous devez en extraire File . Cependant, toutes les URL de ressources ne peuvent pas être converties en File s.

Et y a-t-il un object Ressource?

Du sharepoint vue de JRE, ce n’est qu’un terme. Certains frameworks vous fournissent une telle classe (par exemple, Spring’s Resource ).

Je suis totalement confus en ce moment – principalement à cause de la terminologie, je suppose. Est-ce que quelqu’un peut me guider à travers les différences ou fournir quelques liens vers du matériel à l’épreuve des mannequins? Surtout l’URI à l’URL et la ressource au fichier? Pour moi, on a l’impression qu’ils devraient être la même chose, respectivement …

La terminologie est déroutante et parfois déroutante, et naît principalement de l’évolution de Java en tant qu’API et en tant que plate-forme au fil du temps. Pour comprendre la signification de ces termes, il est important de reconnaître deux éléments qui influencent la conception de Java:

  • Rétrocompatibilité. Les anciennes applications devraient fonctionner sur des installations plus récentes, idéalement sans modification. Cela signifie qu’une ancienne API (avec ses noms et sa terminologie) doit être conservée dans toutes les nouvelles versions.
  • Multiplateforme L’API doit fournir une abstraction utilisable de sa plate-forme sous-jacente, qu’il s’agisse d’un système d’exploitation ou d’un navigateur.

Je vais parcourir les concepts et comment ils sont apparus. Je répondrai ensuite à vos autres questions spécifiques, 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 utilise ceci pour faire référence à un “fichier” qui peut ne pas être un fichier mais représente un élément de données nommé. Il ne dispose pas d’une 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.

Étant donné qu’un des premiers objectives 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 / permissions très limités, Java établit une différence (théorique) système de fichiers) et une ressource (quelque chose qu’il doit lire). C’est pourquoi la lecture de quelque chose relatif à l’application (icons, fichiers de classes, etc.) s’effectue via ClassLoader.getResource et non via la classe File.

Malheureusement, parce que “ressource” est aussi 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 la classe ResourceBundle , UIResource , Resource ) qui ne sont pas, en 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)

Une représentation abstraite des noms de fichiers et de répertoires.

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 plate-forme hôte interprète en fonction de ses propres parameters, 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’access 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, alors File en lira les entrées contenues.

URL (java.net, 1.0)

L’URL de classe représente un localisateur de ressources uniforme, un pointeur vers une “ressource” sur le Web. Une ressource peut être quelque chose d’aussi simple qu’un fichier ou un répertoire, ou peut être une référence à un object plus compliqué, tel qu’une requête à une firebase database ou à un moteur de recherche.

Parallèlement au 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: en tant que chaîne structurée qui pointe vers une ressource. URL contient en outre un schéma qui indique comment atteindre la ressource (avec “file:” étant “demander à la plate-forme hôte”), et permet donc de pointer sur des ressources via HTTP, FTP, dans un JAR et autres.

Malheureusement, les URL viennent avec leur propre syntaxe et terminologie, y compris l’utilisation de “fichier” et “chemin”. Si 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 fichier et a répondu aux besoins du système tel qu’il était imaginé au début des années 90.

URI (java.net, 1.4)

Représente une référence d’URI (Uniform Resource Identifier).

L’URI est une abstraction (légère) par rapport à l’URL. La différence entre l’URI et l’URL est conceptuelle et surtout académique, mais l’URI est mieux définie au sens formel et couvre un éventail plus large de cas d’utilisation. Comme l’URL et l’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 à déplacer entre elles.

En Java, la principale différence entre URL et URI est qu’une URL peut être résolue , ce que l’application peut vouloir un stream InputStream; un URI est traité plus comme un thingamajig abstrait qui pourrait indiquer quelque chose de résolvable (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 d’access (java.nio.file, 1.7)

Un object pouvant être utilisé pour localiser un fichier dans un système de fichiers. Il représente généralement un chemin de fichier dépendant du système.

La nouvelle API de fichiers, iconifiée dans l’interface Path, offre une flexibilité beaucoup plus grande que celle offerte par la classe File. 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 plate-forme hôte, Path est plus générique: il représente un fichier (ressource) dans un système de fichiers arbitraire .

Path élimine le recours 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, d’une représentation multi-racine du classpath de l’application, ou de tout ce qui peut être représenté via l’interface FileSystem et son pilote, FileSystemProvider. Il apporte la puissance du “assembly” 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.


Maintenant, si j’ai un localisateur qui référence une classe ou un package dans un fichier jar, est-ce que ces deux éléments (c.-à-d. Les chaînes d’un fichier) seront différents?

Improbable. Si le fichier JAR se trouve sur le système de fichiers local, vous ne devriez pas avoir de composant de requête. Par conséquent, URL.getPath et URL.getFile doivent renvoyer le même résultat. Toutefois, choisissez celui dont vous avez besoin: les URL de fichiers ne contiennent généralement pas de composants de requête, mais je pourrais certainement en append un.

Enfin et surtout, pourquoi ai-je besoin d’un object File? pourquoi une ressource (URL) n’est-elle pas suffisante?

L’URL peut ne pas suffire, car File vous donne access à des données de maintenance telles que les permissions (lisibles, inscriptibles, exécutables), le type de fichier (je suis 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 Fichier si vous avez access à Path. Certaines API plus anciennes peuvent nécessiter un fichier, cependant.

(Et y a-t-il un object Ressource?)

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 .