web-dev-qa-db-ja.com

Javaのリソース、URI、URL、パス、ファイルの違いは何ですか?

私は現在Javaコードの一部を見ており、パスを文字列として取得し、URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);を使用してURLを取得し、String path = resource.getPath()を呼び出して、最後にnew File(path);を実行します。

ああ、URL url = resource.toURI();String file = resource.getFile()への呼び出しもあります。

私は今完全に混乱しています-主に用語のせいだと思います。誰かが違いを教えてくれたり、ダミーの証拠資料へのリンクをいくつか教えてもらえますか?特にURLへのURIおよびResource to File?私には、それらはそれぞれ同じものでなければならないように感じています...

getFile()getPath()の違いは次のとおりです。 rl.getFile()とgetpath()の違いは何ですか? 文字列を返すために、おそらく私の心の状態に多くのことを追加します...)

さて、jarファイル内のクラスまたはパッケージを参照するロケーターがある場合、それら2つ(つまり、ファイル文字列のパス)は異なりますか?

resource.toString()は、結局、jar:file:/C:/path/to/my.jar!/com/example/を提供します(感嘆符に注意してください)。

URIURLの違いは、Javaで前者はスペースをエンコードしないということですか? Cf. Javaで競合するファイル、URI、およびURL (この回答は、2つの用語の一般的、概念的な違いをかなりよく説明しています: RIs特定およびURLの位置を特定;

最後に-そして最も重要なこと-なぜFileオブジェクトが必要なのですか?なぜリソース(URL)が足りないのですか?(そして、リソースオブジェクトはありますか?)

この質問が少し整理されていない場合は申し訳ありません。それは単に私が持っている混乱を反映しています... :)

86
Christian

UPDATE 2017-04-12チェック JvRの答え には、より網羅的で正確な説明が含まれています!


私は自分自身が100%答える能力があるとは考えていないことに注意してください、しかしそれでもいくつかのコメントがあります:

  • Fileは、ファイルシステム経由でアクセス可能なファイルまたはディレクトリを表します
  • resourceは、アプリケーションによってロードできるデータオブジェクトの 総称 です
    • 通常、resourcesは、アプリケーション/ライブラリとともに配布され、クラスローディングメカニズムを介してロードされるファイルです(クラスパスに存在する場合)
  • URL#getPathはURLのパス部分のゲッターです(protocol://Host/path?query
  • URL#getFile JavaDocごとにpath+queryが返されます

Javaでは、URIは汎用識別子自体を操作するための単なるデータ構造です。

一方、URLは実際にはリソースロケーターであり、登録済みURLStreamHandlersを介して実際にリソースを読み取る機能を提供します。

URLはファイルシステムリソースにつながる可能性があり、file://プロトコルを使用してすべてのファイルシステムリソースのURLを構築できます(したがってFile <-> URL関係)。

また、URL#getFileJava.io.Fileとは無関係であることにも注意してください。


Fileオブジェクトが必要な理由;なぜリソース(URL)が足りないのですか?

十分です。ファイルのみで機能するコンポーネントにリソースを渡したい場合のみ、Fileを取得する必要があります。ただし、すべてのリソースURLをFilesに変換できるわけではありません。

また、Resourceオブジェクトはありますか?

JREの観点から見ると、これは単なる用語です。一部のフレームワークは、そのようなクラスを提供します(例: Spring's Resource )。

40
Pavel Horal

私は今完全に混乱しています-主に用語のせいだと思います。誰かが違いを教えてくれたり、ダミーの証拠資料へのリンクをいくつか教えてもらえますか?特にURLのURIとファイルのリソース?私には、それらはそれぞれ同じものでなければならないように感じています...

用語は紛らわしく、時には混乱を招き、ほとんどがJavaのAPIとしての進化と、時間の経過に伴うプラットフォームとしての進化から生まれます。これらの用語がどのように機能するかを理解するには、Javaの設計に影響を与える2つのことを認識することが重要です。

  • 下位互換性。 古いアプリケーションは、理想的には変更せずに、新しいインストールで実行する必要があります。これは、古いAPI(名前と用語)をすべての新しいバージョンで維持する必要があることを意味します。
  • クロスプラットフォーム。 APIは、オペレーティングシステムであろうとブラウザであろうと、基盤となるプラットフォームの使用可能な抽象化を提供する必要があります。

概念とそれらがどのようになったかについて説明します。最初の部分で何かを参照する必要があるかもしれないので、その後、他の具体的な質問に答えます。

「リソース」とは何ですか?

検索および読み取りが可能な抽象的で汎用的なデータ。 大まかに言って、Javaはこれを使用して、ファイルではないかもしれないが名前付きのデータを表す「ファイル」を参照します。Javaには直接のクラスまたはインターフェース表現はありませんが、そのプロパティ(配置可能、読み取り可能)のため、多くの場合URLで表されます。

Javaの初期の設計目標の1つは、権限/特権/セキュリティクリアランスが非常に制限されたサンドボックスアプリケーション(アプレット!)としてブラウザ内で実行することであったため、Javaが明確になります(理論的)ファイル(ローカルファイルシステム上のもの)とリソース(読み取る必要のあるもの)の違い。 これが、アプリケーションに関連する何か(アイコン、クラスファイルなど)の読み取りがFileクラスではなくClassLoader.getResourceを介して行われる理由です。

残念ながら、「リソース」はこの解釈の有用な一般用語outsideであるため、非常に具体的なものに名前を付けるためにも使用されます(クラス ResourceBundleUIResourceリソース )、この意味では、リソースではありません。

リソース(へのパス)を表す主なクラスは、 Java.nio.file.PathJava.io.FileJava.net.URI 、および Java.netです。 .URL

ファイル (Java.io、1.0)

ファイルとディレクトリのパス名の抽象的な表現。

Fileクラスは、プラットフォームのネイティブファイルシステムを介して到達可能なリソースを表します。ファイルの名前のみが含まれているため、ホストプラットフォームが独自の設定、ルール、および構文に従って解釈するのは、実際にはより多くのパス(後述)です。

Fileは何かlocalを指す必要はないことに注意してください。ホストプラットフォームがファイルアクセスのコンテキストで理解するものだけです。 WindowsのUNCパス。 OSでZipファイルをファイルシステムとしてマウントすると、Fileは含まれているエントリを正常に読み取ります。

URL (Java.net、1.0)

クラスURLは、World Wide Web上の「リソース」へのポインタであるUniform Resource Locatorを表します。リソースは、ファイルやディレクトリのような単純なものでも、データベースや検索エンジンへのクエリなど、より複雑なオブジェクトへの参照でもかまいません。

リソースの概念と並行して、URLは、Fileクラスがホストプラットフォーム内のファイルを表すのと同じ方法でリソースを表します。リソースを指す構造化された文字列。 URLには、リソースへの到達方法を示すスキーム(「file:」は「ホストプラットフォームに問い合わせる」)が追加されているため、HTTP、FTP、JAR内などでリソースを指すことができます。

残念ながら、URLには「ファイル」や「パス」の使用など、独自の構文と用語が付属しています。 URLがファイルURLの場合、URL.getFileは、参照ファイルのパス文字列と同じ文字列を返します。

Class.getResourceはURLを返します。これは、Fileを返すよりも柔軟性があり、1990年代初頭に想定されていたシステムのニーズに応えてきました。

URI (Java.net、1.4)

Uniform Resource Identifier(URI)参照を表します。

URIはURLの(わずかな)抽象化です。 URIとURLの違いは概念的であり、ほとんどが学術的なものですが、URIは正式な意味でより適切に定義されており、幅広いユースケースをカバーしています。 URLとURIは同じものではないため、それらを表す新しいクラスが導入され、URI.toURLメソッドとURL.toURIメソッドが相互に移動します。

Javaでは、URLとURIの主な違いは、URLが解決可能であることを期待していることです。これは、アプリケーションがInputStreamを必要とするものです。 URIは抽象的なもののように扱われ、mightは解決可能な何かを指します(通常はそうします)が、その意味と到達方法は、コンテキストと解釈に対してよりオープンです。

パス (Java.nio.file、1.7)

ファイルシステム内のファイルを見つけるために使用できるオブジェクト。通常、システムに依存するファイルパスを表します。

Pathインターフェースでアイコン化された新しいファイルAPIは、Fileクラスが提供できるよりもはるかに高い柔軟性を可能にします。 Pathインターフェースは、Fileクラスの抽象化であり、 New IO File API の一部です。ホストプラットフォームが理解するようにFileが必然的に「ファイル」を指す場合、Pathはより一般的です。は、arbitraryファイルシステム内のファイル(リソース)を表します。

パスは、ホストプラットフォームのファイルという概念への依存を取り除きます。 Zipファイルのエントリ、FTPまたはSSH-FSを介して到達可能なファイル、アプリケーションのクラスパスのマルチルート表現、またはFileSystemインターフェイスとそのドライバーであるFileSystemProviderを介して意味のある表現が可能なものです。ファイルシステムを「マウント」する力をJavaアプリケーションのコンテキストにもたらします。

ホストプラットフォームは「デフォルトファイルシステム」で表されます。 File.toPathを呼び出すと、デフォルトのファイルシステムでパスを取得します。


さて、jarファイル内のクラスまたはパッケージを参照するロケーターがある場合、それら2つ(つまり、ファイル文字列のパス)は異なりますか?

ありそうもない。 jarファイルがローカルファイルシステムにある場合は、クエリコンポーネントを使用しないでください。したがって、URL.getPathURL.getFileは同じ結果を返します。ただし、必要なものを選択してください。ファイルURLには通常、クエリコンポーネントがない場合がありますが、いずれにしてもクエリコンポーネントを追加できます。

最後に-そして最も重要なこと-Fileオブジェクトが必要な理由;なぜリソース(URL)が足りないのですか?

Fileを使用すると、アクセス許可(読み取り可能、書き込み可能、​​実行可能)、ファイルの種類(ディレクトリですか?)、ローカルファイルシステムを検索および操作する機能などのハウスキーピングデータにアクセスできるため、URLで十分ではない場合があります。これらが必要な機能である場合、ファイルまたはパスが提供します。

パスにアクセスできる場合、ファイルは必要ありません。ただし、一部の古いAPIではFileが必要になる場合があります。

(そしてResourceオブジェクトはありますか?)

いいえ、ありません。そのような名前が付けられたものはたくさんありますが、それらはClassLoader.getResourceの意味ではリソースではありません。

40
JvR

Pavel Horalの答え はいいです。

彼が言うように、Wordの「ファイル」はURL#getFileJava.io.Fileでまったく異なる(実際には無関係の)意味を持っています-それは混乱の一部かもしれません。

追加するだけ:

  • Javaのresourceは抽象的な概念であり、読み取り可能なデータのソースです。リソースの場所(またはアドレス)は、JavaでURLオブジェクトによって表されます。

  • resourceは、ローカルファイルシステム内の通常のファイルに対応できます(具体的には、URLfile://で始まる場合)。しかし、リソースはより一般的です(jarに格納されているファイル、ネットワークから読み込まれるデータ、メモリから読み込まれるデータなど)。また、File(通常のファイル以外のもの:ディレクトリ、リンク)を作成して書き込むこともできるため、さらに制限されます。

  • Java aFileオブジェクトは、実際には「ファイル」ではなく、場所(フルネーム、パス付き)を表すことを忘れないでくださいファイル。したがって、Fileを使用するとリソースにアクセス(およびオープン)できるため、URLオブジェクトを使用すると、ファイルを検索(およびオープン)できます。 (Javaにはリソースを表すResourceクラスはありませんが、ファイルを表すクラスはありません!もう一度:Fileはファイルではなく、ファイルのパスです)。

11
leonbloy

私が理解しているように、次のように分類できます。

Webベース:URIおよびURL。

  • URL:URLは、interntの明確な場所です(stackoverflow.comのような通常のWebアドレス)
  • URI:これまでのURLはURIです。しかし、URIには「mailto:」のようなものを含めることもできるので、URIも「スクリプト」のようなものです。

ローカル:リソース、パス、およびファイル

  • リソース:リソースは、jar内のファイルです。これらは、jar /コンテナからファイルをロードするために使用されます。
  • パス:パスは基本的に文字列です。ただし、複数の文字列を連結したり、文字列にファイルを追加したりする便利な機能がいくつか付属しています。構築しているパスが有効であることを確認します。
  • ファイル:これはディレクトリまたはファイルへの参照です。ファイルの変更、それらのオープンなどに使用されます。

それらが1つのクラスにマージされると簡単になります-彼らは本当に混乱しています:D

これがあなたのお役に立てば幸いです:)

(ドキュメントを見てみました-docs.Oracle.comを見てください)

3
Cyphrags

ファイルは、ローカルファイルシステム内のエンティティの抽象的な表現です。

パスは通常、ファイルシステム内のファイルの場所を示す文字列です。通常、ファイル名は含まれません。そのため、c:\ documents\mystuff\stuff.txtのパスは「C:\ documents\mystuff」の値になります。絶対ファイル名とパスの形式は、ファイルシステムごとに大きく異なります。

URLはURIのサブセットであり、URLは通常、http経由でアクセス可能なリソースを表します。私は何かがURI対URLでなければならないときについて、なんらかの鉄則が存在するとは思わない。 URIは、bitcoin:// params、 http://something.com?param=value などの「protocol:// resource-identifier」の形式の文字列です。 URLなどのクラスは通常、文字列をラップし、Stringが提供する理由のないユーティリティメソッドを提供します。

少なくともあなたが話しているという意味では、リソースのようなものはありません。メソッドの名前がgetResourceであるからといって、Resourceタイプのオブジェクトを返すというわけではありません。

最終的に、クラスのメソッドが何をするかを理解する最良の方法は、コード内でそのインスタンスを作成し、メソッドを呼び出してからデバッグモードでステップスルーするか、結果をSystem.outに送信することです。

0
Jim W