1. ホーム
  2. java

[解決済み] getResourceAsStream() vs FileInputStream (ファイルインプットストリーム)

2022-04-20 02:44:23

質問

ウェブアプリでファイルを読み込もうとすると FileNotFound を使用すると、例外が発生します。 FileInputStream . しかし、同じパスを使用して、次のようにすると、ファイルを読み込むことができました。 getResourceAsStream() . この2つの方法の違いは何でしょうか?また、なぜ一方はうまくいき、もう一方はうまくいかないのでしょうか?

どのように解決するのですか?

その java.io.File とコンソートはローカルディスクのファイルシステム上で動作します。問題の根本的な原因は 相対 のパスは java.io は、現在の作業ディレクトリに依存します。すなわち、JVM(あなたの場合、ウェブサーバーのもの)が開始されるディレクトリです。これは、例えば C:\Tomcat\bin または全く別のものですが、このように ではなく C:\Tomcat\webapps\contextname といった具合になります。通常のEclipseプロジェクトでは、次のようになります。 C:\Eclipse\workspace\projectname . 現在の作業ディレクトリは、次のようにして知ることができます。

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

しかし、作業ディレクトリはプログラムではどうにも制御できません。本当は 絶対 のパスを File 相対パスの代わりにAPIを使用します。例 C:\full\path\to\file.ext .

Java(Web)アプリケーションでは、絶対パスをハードコードしたり推測したりすることは避けたいものです。それは移植性の問題でしかありません(つまり、システムXでは動作するが、システムYでは動作しない)。通常のやり方は、その種のリソースを クラスパス または、クラスパスにフルパスを追加します。 src フォルダとビルドパスをそれぞれ指定します。) こうすることで、これらのファイルを ClassLoader によって ClassLoader#getResource() または ClassLoader#getResourceAsStream() . これはクラスパスの "ルート" からの相対パスでファイルを見つけることができます。ウェブアプリケーション(あるいは複数のクラスローダを使用する他のアプリケーション)では ClassLoader が返すように Thread.currentThread().getContextClassLoader() を使用することで、ウェブアプリケーションのコンテキストの外側を見ることができます。

Webappsにおけるもうひとつの選択肢は ServletContext#getResource() とその対極にある ServletContext#getResourceAsStream() . にあるファイルにアクセスすることができます。 web フォルダを含む、Webapp プロジェクトの /WEB-INF フォルダーに格納されます。また ServletContext はサーブレットの中で、継承された getServletContext() メソッドを使えば、そのまま呼び出すことができます。

こちらもご覧ください。