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

je regarde un morceau de code Java en ce moment, et il prend un chemin comme une chaîne et obtient son URL en utilisant URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString); , puis appelle String path = resource.getPath() et finalement exécute new File(path); .

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

je suis totalement confus en ce moment - principalement à cause de la terminologie, je suppose. Est-ce que quelqu'un peut s'il vous plaît me guider à travers les différences, ou fournir quelques liens vers des matériaux à L'épreuve des mannequins? En particulier URI À URL et ressource pour le fichier ? Pour moi, c'est comme s'ils devaient ê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 retourner des cordes, ce qui ajoute probablement beaucoup à mon état d'esprit...)

maintenant, si j'ai un localisateur qui fait référence à une classe ou à un paquet dans un fichier jar, est-ce que ces deux-là (c'est-à-dire le chemin des chaînes de fichiers) seront différents?

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

est la différence entre URI et URL en Java que le premier ne Code pas les espaces? Cf. Les Fichiers, Les Uri, et des URLs en conflit en Java (cette réponse explique la générale, conceptuelle différence entre les deux termes assez bien: URIs identifier et URLs locate; )

enfin - et le plus important - pourquoi ai-je besoin de File objet; pourquoi une ressource ( URL ) n'est-elle pas suffisante? (et y a-t-il un article ressource?)

Désolé si cette question est un peu non organisé; elle reflète simplement la confusion que j'ai... :)

79
demandé sur Community 2015-01-08 19:43:11

5 réponses

mise à JOUR 2017-04-12 Vérifier JvR la réponse de car il contient plus exhaustive et exacte explication!


s'il vous Plaît noter que je ne me considère pas comme 100% compétent pour y répondre, mais néanmoins, voici quelques commentaires:

  • File représente un fichier ou un répertoire accessible par système de fichiers
  • ressource est un terme générique pour un objet de données qui peut être chargé par l'application
    • habituellement ressources sont des fichiers distribué avec l'application / de la bibliothèque et de les charger via la classe mécanisme de chargement (quand ils se trouvent sur le chemin de classe)
  • URL#getPath est de lecture sur le chemin de la partie de l'URL ( protocol://host/path?query )
  • URL#getFile selon JavaDoc retourne path+query

en Java, URI est juste une structure de données pour manipuler l'identifiant générique lui-même.

URL d'un autre côté est vraiment un localisateur de ressources et vous offre des fonctionnalités pour lire réellement la ressource via enregistré URLStreamHandler S.

URLs peuvent conduire à des ressources de système de fichiers et vous pouvez construire URL pour chaque ressource de système de fichiers en utilisant file:// protocole (d'où la relation File <-> URL ).

sachez aussi que URL#getFile n'est pas lié à java.io.File .


Pourquoi ai-je besoin D'un objet fichier; Pourquoi une ressource (URL) n'est-elle pas suffisante?

C'est assez. Seulement, si vous souhaitez passer de la ressource à un élément qui ne peut fonctionner qu'avec des fichiers, vous avez besoin pour obtenir File . Cependant, pas toutes les ressources Les URLs peuvent être converties en File s.

et y a-t-il un objet ressource?

du point de vue de JRE, c'est juste un terme. Certains cadres vous fournissent une telle classe (par exemple ressource du ressort ).

37
répondu Pavel Horal 2017-05-23 12:26:36

je suis totalement confus en ce moment - principalement à cause de la terminologie, je suppose. Est-ce que quelqu'un peut s'il vous plaît me guider à travers les différences, ou fournir quelques liens vers des matériaux à L'épreuve des mannequins? Particulièrement URI À URL et ressource à Fichier? Pour moi, c'est comme s'ils devaient être la même chose, respectivement...

la terminologie est confuse et parfois confuse, et la plupart du temps né de L'évolution de Java à la fois comme une API et comme une plate-forme sur temps. Pour comprendre comment ces termes sont venus à signifier ce qu'ils font, il est important de reconnaître deux choses qui influencent la conception de Java:

  • rétrocompatibilité. les anciennes applications doivent 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.
  • Cross-platform. L'API doit fournir un produit de l'abstraction de sa plateforme sous-jacente, qu'il s'agisse d'un système d'exploitation ou navigateur.

je vais parcourir les concepts et leur genèse. Je répondrai à vos autres questions spécifiques après cela, parce que je pourrais devoir faire référence à quelque chose dans la première partie.

qu'est Ce qu'une "Ressource"?

une donnée abstraite et générique qui peut être localisée et lue. dit vaguement, Java utilise ceci pour faire référence à un" fichier " qui peut ne pas être un fichier mais qui représente un morceau de données nommé. il n'a pas de classe directe ou de représentation d'interface en Java , mais en raison de ses propriétés (localisable, lisible) 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, comme une application sandboxed (applets!) avec très peu de droits/privilèges / habilitation de sécurité, Java fait une différence (théorique) claire entre un fichier (quelque chose sur le système de fichiers local) et une ressource (quelque chose qu'il doit lire). c'est pourquoi lire quelque chose relatif à l'application (icônes, fichiers de classe, et ainsi de suite) se fait par ClassLoader.getResource et non par la classe de fichier.

malheureusement, parce que "ressource" est aussi un terme générique utile en dehors de 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, dans ce sens, une ressource.

les classes principales représentant (un chemin vers) une ressource sont java.nio.fichier.Chemin , java.io.Fichier , java.net.URI , et java.net.URL .

File (java.io, 1.0)

Une représentation abstraite de fichier et de répertoire des chemins d'accès.

la classe de fichier représente une ressource qui est accessible par le système de fichiers natif de la plate-forme . Il ne contient que le nom du fichier, donc c'est plus un chemin (Voir plus loin) que la plate-forme hôte interprète selon ses propres paramètres, règles, et de la syntaxe.

notez que le fichier N'a pas besoin de pointer vers quelque chose local , juste quelque chose que la plate-forme hôte comprend dans le contexte de l'accès au fichier, par exemple un chemin UNC dans Windows. Si vous montez un fichier ZIP comme un système de fichiers dans votre OS, puis fichier Lira ses entrées contenues juste très bien.

URL (java.net, 1.0)

L'URL de classe représente un uniforme Localisateur de ressources, un pointeur vers une "ressource" sur le World Wide Web. Une ressource peut être quelque chose d'aussi simple qu'un fichier ou un répertoire, ou il peut être une référence à un plus compliqué objet, tel qu'une requête à une base de données ou à un moteur de recherche.

en tandem avec le concept d'une ressource, L'URL représente cette ressource de la même façon que la classe File représente un fichier dans la plate-forme hôte: comme une chaîne structurée qui pointe vers une ressource. URL contient en outre un schéma qui suggère comment atteindre la ressource (avec "file:" étant "demander à la plate-forme hôte"), et permet donc de pointer vers les ressources par HTTP, FTP, à l'intérieur d'un bocal, et ainsi de suite.

malheureusement, les URLs ont leur propre syntaxe et terminologie, y compris l'utilisation de "file" et "path". Dans le cas où L'URL est un fichier-URL, URL.getFile retournera une chaîne identique à la chaîne de chemin du fichier référencé.

Class.getResource renvoie une URL: elle est plus flexible que le fichier de retour, et elle a répondu aux besoins du système comme imaginé au début des années 1990.

URI (java.net, 1.4)

représente une référence D'Identificateur de Ressource (URI) uniforme.

URI est une (légère) abstraction au-dessus de l'URL. la différence entre URI et URL est conceptuelle et surtout universitaire, mais d'URI est mieux défini dans un sens formel, et couvre un large éventail de cas d'utilisation. Parce que 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 de se déplacer entre l'un et l'autre.

en Java, la principale différence entre URL et URI est que une URL porte l'attente d'être résoluble , quelque chose que l'application pourrait vouloir une entrée de; un URI est traité plus comme un thingamajig abstrait que pourrait pointer à quelque chose résoluble (et fait habituellement), mais ce qu'il signifie et comment l'atteindre sont plus ouverts au contexte et l'interprétation.

Chemin (java.nio.dossier, 1.7)

Un objet qui peut être utilisé pour rechercher 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 fichier, iconifiée dans L'interface Path, permet une plus grande flexibilité que la classe de fichier pourrait offrir. L'interface de chemin est une abstraction de la classe de fichier , et fait partie de la nouvelle API de fichier IO . Lorsque le fichier pointe nécessairement vers un" fichier "tel que compris par la plate-forme hôte, le chemin est plus générique: il représente un fichier (ressource) dans un système de fichiers arbitraire .

Path supprime la confiance dans le concept d'un fichier de la plate-forme hôte. Il peut s'agir d'une entrée dans un fichier ZIP, d'un fichier accessible par FTP ou SSH-FS, d'une représentation multi-enracinée du chemin de classe de l'application, ou vraiment de tout ce qui peut être représenté de manière significative par l'interface du système de fichiers et son pilote, FileSystemProvider. Il apporte la puissance de "montage" des systèmes de fichiers dans le cadre d'une application Java.

La plate-forme hôte est représenté 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 fait référence à une classe ou à un paquet dans un fichier jar, est-ce que ces deux-là (c'est-à-dire le chemin des chaînes de fichiers) seront différents?

improbable. Si le fichier jar est sur le système de fichiers local, vous ne devriez pas avoir de composant de requête, donc URL.getPath et URL.getFile devraient retourner le même résultat. Cependant, choisissez celui dont vous avez besoin: file-URLs peut ne pas avoir typiquement des composants de requête, mais je pourrais certainement en ajouter un de toute façon.

enfin - et le plus important-pourquoi ai-je besoin D'un objet fichier; Pourquoi une ressource (URL) n'est-elle pas suffisante?

URL pourrait ne pas être suffisant parce que le fichier vous donne accès aux données de ménage telles que les autorisations (lisible, writable, exécutable), le type de fichier (suis-je un répertoire?), et la capacité de rechercher et manipuler le système de fichiers local. Si ce sont des fonctionnalités dont vous avez besoin, alors File ou Path les fournissent.

vous n'avez pas besoin de fichier si vous avez accès à Path. Certains API plus anciennes peuvent cependant nécessiter un fichier.

(et y a-t-il un article 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 .

29
répondu JvR 2016-11-22 13:51:13

la réponse de Pavel Horal est agréable.

comme il le dit, le mot" file "a des significations totalement différentes (pratiquement sans rapport) dans URL#getFile vs java.io.File - peut être que cela fait partie de la confusion.

juste pour ajouter:

  • Un ressource en Java est un concept abstrait, une source de données qui peuvent être lus. L'emplacement (ou l'adresse) d'un la ressource est représentée en Java par un objet URL .

  • a resource peut correspondre à un fichier régulier dans le système de fichiers local (en particulier, lorsque son URL commence par file:// ). Mais une ressource est plus générale (elle peut aussi être un fichier stocké dans un bocal, ou des données à lire à partir du réseau, ou de la mémoire, ou...). Et c'est aussi plus limité, car un File (en plus d'être autre chose qu'un fichier régulier: un répertoire, un lien) peut aussi être créé et écrit.

  • Souvenez-vous en Java un File objet n'a pas vraiment d'représente "un fichier", mais l'emplacement (le nom complet, avec chemin d'accès) d'un fichier. De la sorte, un File objet vous permet de localiser et ouvrir un fichier, comme un URL vous permet d'accéder (et ouverte) une ressource. (Il n'y a pas de classe Resource en Java pour représenter une ressource, mais il n'y en a pas pour représenter un fichier! une fois de plus : File n'est pas un fichier, c'est le chemin d'accès d'un fichier).

11
répondu leonbloy 2017-05-23 12:10:45

si je les comprends bien, vous pouvez les classer comme suit:

Basée sur le Web: les Uri et Url.

  • URLs: une URL est un emplacement défini sur l'internt (juste une adresse web normale comme - stackoverflow.com)
  • URIs: chaque URL est une URI. Mais URIs peut aussi contenir des choses comme "mailto:", donc ils sont aussi, et bien quelque chose d'un "script" je dirais.

et local: ressource, chemin et Dossiers

  • ressource: les ressources sont des fichiers à l'intérieur de votre pot. Ils sont utilisés pour charger des fichiers dans des pots / conteneurs.
  • Chemin: Un chemin est une chaîne. Mais il est livré avec quelques fonctions pratiques pour concaténer plusieurs chaînes, ou ajouter des fichiers à une chaîne. Il s'assure que le chemin que vous construisez est valide.
  • Fichier: référence à un répertoire ou à un fichier. Il est utilisé pour modifier les fichiers, les ouvrir, etc.

il serait plus facile de les fusionner en une seule classe - ils sont vraiment déroutants :d

j'espère que cela vous aide à vous :)

(je viens de jeter un oeil à la documentation - regarder docs.oracle.com)

3
répondu Cyphrags 2015-01-08 17:02:08

Un Fichier est une représentation abstraite d'une entité dans le système de fichiers local.

Un chemin d'accès est généralement une chaîne de caractères indiquant l'emplacement d'un fichier dans un système de fichiers. Il n'inclut généralement pas le nom du fichier. Donc c:\documents\mystuff\stuff.txt aurait un chemin avec la valeur de "C:\documents\mystuff" évidemment, le format des noms de fichiers absolus et des chemins varierait énormément d'un système de fichiers à l'autre.

URL est un susbset D'URI avec URL représentant habituellement des ressources accessibles par http. Je ne pense pas qu'il y ait une sorte de règle absolue quand quelque chose doit être une URL URI vs une URL. Les uri sont des chaînes de caractères sous la forme de "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 d'utilité que la chaîne n'aurait aucune raison de fournir.

aucune ressource, du moins pas dans le sens, vous êtes en train de parler. Ce n'est pas parce qu'une méthode est appelée getResource qu'elle retourne un objet de type Resource.

finalement la meilleure façon de comprendre ce que font les méthodes D'une classe est de créer une instance de celui-ci dans votre code, appeler les méthodes et puis soit étape par dans le mode de débogage ou envoyer les résultats au système.hors.

0
répondu Jim W 2015-01-08 17:08:49