web-dev-qa-db-ja.com

getResourceAsStream()vs FileInputStream

Webappでファイルをロードしようとしていて、FileNotFoundを使用したときにFileInputStream例外が発生していました。ただし、同じパスを使用して、getResourceAsStream()を実行したときにファイルをロードできました。 2つの方法の違いは何ですか?また、なぜ一方が機能し、他方が機能しないのですか?

168
Vivin Paliath

Java.io.File およびconsortsは、ローカルディスクファイルシステムに作用します。問題の根本的な原因は、Java.iorelativeパスが現在の作業ディレクトリに依存していることです。つまりJVM(あなたの場合:ウェブサーバーのもの)が開始されるディレクトリ。これは、たとえばC:\Tomcat\binまたはまったく異なるものである場合がありますが、notC:\Tomcat\webapps\contextnameまたは予想されるものは何でもかまいません。通常のEclipseプロジェクトでは、C:\Eclipse\workspace\projectnameになります。現在の作業ディレクトリについては、次の方法で学習できます。

System.out.println(new File(".").getAbsolutePath());

ただし、作業ディレクトリはプログラムで制御することはできません。 File APIでは、相対パスの代わりにabsoluteパスを使用することを本当に好むはずです。例えば。 C:\full\path\to\file.ext

Java(web)アプリケーションの絶対パスをハードコードしたり推測したりしたくない場合。これは移植性の問題です(つまり、システムXで実行されますが、システムYでは実行されません)。通常の方法では、これらの種類のリソースをclasspathに配置するか、クラスパスにフルパスを追加します(IDEで) _ Eclipseのように、それぞれsrcフォルダーと「ビルドパス」)。この方法では、 ClassLoader#getResource() または ClassLoader#getResourceAsStream() を使用して、ClassLoaderを使用してそれらを取得できます。偶然にわかったように、クラスパスの「ルート」に関連するファイルを見つけることができます。 Webアプリケーション(または複数のクラスローダーを使用する他のアプリケーション)では、このためにThread.currentThread().getContextClassLoader()によって返されるClassLoaderを使用することをお勧めします。これにより、webappコンテキストの「外側」も確認できます。

Webappsのもう1つの代替手段は、 ServletContext#getResource() とそれに対応する ServletContext#getResourceAsStream() です。 /WEB-INFフォルダーを含む、webappプロジェクトのパブリックwebフォルダーにあるファイルにアクセスできます。 ServletContextは、継承された getServletContext() メソッドによってサーブレットで使用できます。そのまま呼び出すことができます。

こちらもご覧ください:

253
BalusC

getResourceAsStreamは、既に学習したように、Webアプリに対して適切な方法です。

その理由は、WebアプリケーションをWARにパッケージ化すると、ファイルシステムからの読み取りが機能しないためです。これは、Webアプリをパッケージ化する適切な方法です。絶対ファイルパスやアプリサーバーがインストールされている場所に依存していないため、そのように移植可能です。

26
duffymo

FileInputStreamは、Javaプロセスの作業ディレクトリからの相対パスとしてコンストラクターに渡すファイルパスをロードします。通常、Webコンテナーでは、これはbinフォルダーのようなものです。

getResourceAsStream()は、相対的なファイルパスをロードします アプリケーションのクラスパスから

13
matt b

FileInputStreamクラスは、基になるファイルシステムと直接連携します。問題のファイルがそこに物理的に存在しない場合、ファイルを開くことができません。 getResourceAsStream()メソッドの動作は異なります。呼び出されたクラスのClassLoaderを使用して、リソースを見つけてロードしようとします。これにより、たとえばjarファイルに埋め込まれたリソースを見つけることができます。

12
Dirk

classname.getResourceAsStream()は、classnameのクラスローダーを介してファイルをロードします。クラスがjarファイルから取得された場合、そこからリソースがロードされます。

FileInputStreamは、ファイルシステムからファイルを読み取るために使用されます。

6
Lachlan Roche

File Read(Java.io)およびResource Read(ClassLoader.getResourceAsStream())としてマークすることにより、両方の使用法を分離することにより、ここにいます。

ファイル読み取り- 1.ローカルファイルシステムで動作します。 2.現在のJVM起動ディレクトリから要求されたファイルをルートとして探します。

リソース読み取り- 1.クラスパスで動作します2.現在または親のクラスローダーのクラスパスでファイル/リソースを探します。 3. warやjarなどのパッケージ化されたファイルからファイルをロードしようとする場合に理想的です。

0
Aditya Bhuyan