私は今完全に混乱しています-専門用語のせいだと思います。誰かが違いを教えてくれますか、それともダミープルーフ素材へのリンクをいくつか提供してくれますか?特にURLへのURIとファイルへのリソース?私には、それぞれ同じものであるように感じます...
用語は紛らわしく、時には混乱を招き、ほとんどがJavaのAPIとしての進化と、プラットフォームとしての進化の両方から生まれました。これらの用語が何を意味するのかを理解するには、Javaの設計に影響を与える2つのことを認識することが重要です。
- 下位互換性。 古いアプリケーションは、理想的には変更せずに、新しいインストールで実行する必要があります。つまり、すべての新しいバージョンで古いAPI(名前と用語を含む)を維持する必要があります。
- クロスプラットフォーム。 APIは、オペレーティングシステムであれブラウザであれ、基盤となるプラットフォームの使用可能な抽象化を提供する必要があります。
コンセプトとそれらがどのようになってきたのかについて説明します。最初の部分で何かを参照する必要があるかもしれないので、その後、他の特定の質問に答えます。
「リソース」とは何ですか?
検索して読み取ることができる抽象的な一般的なデータ。 大まかに言って、Javaはこれを使用して、ファイルではないが名前付きのデータを表す「ファイル」を参照します。 Javaには直接のクラスまたはインターフェース表現はありませんが、そのプロパティ(配置可能、読み取り可能)のため、URLで表されることがよくあります。
Javaの初期の設計目標の1つはブラウザー内で実行され、サンドボックスアプリケーション(アプレット!)として非常に制限された権限/特権/セキュリティクリアランスを備えていたため、Javaはファイル(ローカル上の何か)ファイルシステム)およびリソース(読み取る必要があるもの)。 これが、アプリケーションに関連するもの(アイコン、クラスファイルなど)の読み取りClassLoader.getResource
がFileクラスではなく、Fileクラスを通じて行われる理由です。
残念ながら、「リソース」もこの解釈の外では有用な一般的な用語であるため、この意味ではリソースではない非常に具体的なもの(例:ResourceBundle、UIResource、Resource)の名前にも使用されます。
リソース(へのパス)を表す主なクラスは、java.nio.file.Path、java.io.File、java.net.URI、およびjava.net.URLです。
ファイル(java.io、1.0)
ファイルとディレクトリのパス名の抽象的な表現。
Fileクラスは、プラットフォームのネイティブファイルシステムを介して到達可能なリソースを表します。これにはファイルの名前のみが含まれるため、実際には、ホストプラットフォームが独自の設定、ルール、および構文に従って解釈するパス(後述)になります。
Fileはローカルなものを指す必要はなく、ホストプラットフォームがファイルアクセスのコンテキストで理解できるもの(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が解決可能であるという期待を伝えていることです。AN URIは、より抽象的なthingamajigのように扱われるかもしれない何かで解決を指し、(通常)が、その意味とどのようにそれは文脈や解釈により開かれて到達すること。
パス(java.nio.file、1.7)
ファイルシステム内のファイルを見つけるために使用できるオブジェクト。通常、システムに依存するファイルパスを表します。
Pathインターフェースでアイコン化された新しいファイルAPIは、Fileクラスが提供できるよりもはるかに高い柔軟性を可能にします。PathインターフェースはFileクラスを抽象化したもので、New IO File APIの一部です。Fileがホストプラットフォームによって理解される「ファイル」を必ず指す場合、Pathはより一般的です。任意のファイルシステム内のファイル(リソース)を表します。
パスは、ホストプラットフォームのファイルの概念への依存を取り除きます。これは、ZIPファイルのエントリ、FTPまたはSSH-FSを介して到達可能なファイル、アプリケーションのクラスパスのマルチルート表現、またはFileSystemインターフェースとそのドライバーであるFileSystemProviderを介して意味のあるものを表すことができるものであれば何でもかまいません。これは、ファイルシステムを「マウント」する能力をJavaアプリケーションのコンテキストにもたらします。
ホストプラットフォームは「デフォルトのファイルシステム」で表されます。を呼び出すとFile.toPath
、デフォルトのファイルシステムのパスが取得されます。
さて、jarファイル内のクラスまたはパッケージを参照するロケーターがある場合、これら2つ(つまり、ファイル文字列のパス)は異なりますか?
ありそうもない。jarファイルは、ローカルファイルシステム上にある場合は、クエリコンポーネントを持つべきではない、そうURL.getPath
とURL.getFile
同じ結果を返す必要があります。ただし、必要なものを選択します。ファイルURLには通常クエリコンポーネントがない場合がありますが、とにかく1つ追加することができます。
最後に、そして最も重要なこととして、なぜFileオブジェクトが必要なのでしょうか。リソース(URL)が十分でないのはなぜですか?
Fileでは、アクセス許可(読み取り、書き込み、実行可能)、ファイルタイプ(ディレクトリかどうか)、ローカルファイルシステムを検索および操作する機能などのハウスキーピングデータにアクセスできるため、URLでは不十分な場合があります。これらが必要な機能である場合、ファイルまたはパスがそれらを提供します。
パスにアクセスできる場合は、ファイルは必要ありません。ただし、一部の古いAPIではファイルが必要になる場合があります。
(そしてResourceオブジェクトはありますか?)
いいえ、ありません。そのように命名されたものはたくさんありますが、それらはの意味でのリソースではありませんClassLoader.getResource
。
Path
、NIOからFileSystem を見始めることさえしなかった:)