Eclipse でファイルから読み取る必要がある Java アプリケーションを実行するとjava.io.FileNotFoundException
、ファイルが正しいディレクトリにあるにもかかわらず、. コマンドラインからアプリケーションをコンパイルして実行できます。この問題は、複数のプロジェクトとアプリケーションを使用する Eclipse でのみ発生します。ファイルを正しく見つけるために、実行構成またはビルドパスで変更する必要がある設定はありますか?
5 に答える
問題は、アプリケーションが相対パス名を使用している可能性が最も高いです。@BalusC が言うように、相対パス名は問題になる可能性があります。しかし、IMO、彼は「[y]あなたはjava.ioのもので絶対に相対パスを使うべきではない」と言ったとき、行き過ぎです。
アプリケーションが (たとえば)FileInputStream(File)
コンストラクターを使用してファイルを開くと、相対パス名は、File.getAbsolutePath()
.
[...] それ以外の場合、このパス名はシステムに依存する方法で解決されます。UNIX システムでは、現在のユーザー ディレクトリに対して解決することにより、相対パス名が絶対パス名になります。Microsoft Windows システムでは、相対パス名は、パス名で指定されたドライブの現在のディレクトリ (存在する場合) に対して解決することにより、絶対パス名になります。そうでない場合は、現在のユーザー ディレクトリに対して解決されます。
すぐに、「現在のディレクトリ」の概念が Windows と UNIX プラットフォームで異なるニュアンスを持つことがわかります。2 番目の問題は、純粋な Java では現在のディレクトリが何であるかを明確に知ることができず、純粋な Java を使用する現在の JVM 用にそれを変更できないことです。(JVM が起動すると、「user.dir」システム プロパティは現在のディレクトリに設定されますが、アプリケーションがプロパティを変更するのを止めるものは何もないため、完全に依存することはできません。さらに、「user.dir」を変更すると変更されるだけです。空のパスが解決される方法であり、一般的な相対パスではありません。)
それで、あなたはこれについて何をすべきですか?
1 つのオプションは、絶対パス名を使用してファイルを参照することです。これは (ほとんど) すべての場合に信頼できますが、絶対パス名を使用すると、ユーザーがパス名を入力する必要がある場合や、固定 (または構成済み) の絶対パス名を避ける必要がある場合に問題が生じる可能性があります。
2 番目のオプションは、クラスパスの相対パス名を使用して、アプリケーションのインストール ディレクトリを基準にしてファイルを配置することです。
File
これは、それが必要な場合は機能しますが、ライブラリ メソッドにa を渡す必要がある場合は問題が発生します。また、ユーザーのアプリケーション設定を見つけようとしている場合にも役に立ちません。(一般的に、ユーザー設定をインストールディレクトリに入れるのは間違いです...)3 番目のオプションは、別の場所から取得した絶対ディレクトリに関連するファイルに名前を付けることです。例えば
new File(System.getProperty("home.dir"), "foo/bar");
。最後のオプションは、相対パス名を使用することであり、ユーザーが現在のディレクトリを知っていると仮定します。ユーザーがコマンド ラインから実行する多くのアプリケーションでは、これが適切なソリューションです。
Eclipse の特定のケースでは、簡単な解決策があります。アプリケーションの起動に使用している「実行構成」に移動し、「引数」タブを開き、「その他」ラジオボタンをクリックします。次に、起動したアプリケーションの作業ディレクトリとして絶対パス名を入力します。子 JVM が起動されると、指定された作業ディレクトリが現在のディレクトリになります。
Eclipse でデフォルトの Java アプリケーションを作成すると、次のディレクトリ構造が得られます。
./ProjectName/ - ルート ディレクトリ
./ProjectName/bin/ - .class ファイルを含む出力ディレクトリ
./ProjectName/src/ - .java ファイルを含むソース ディレクトリ
アプリケーションが「./data.txt」を要求すると、ルート ディレクトリを基準にして検索されます。これは「作業ディレクトリ」であり、上記のMartinの返信に従って引数タブで構成できます。
コマンドラインから動作すると言いますか?これは、Java バイナリを実行するときに bin または src フォルダー内にいることが原因である可能性があります。この場合の作業ディレクトリは、コマンド プロンプトが現在入っているディレクトリです。たとえば、/src/ ディレクトリに移動し、javac *.java
そこからファイルを実行すると、/src/ ディレクトリ内で "./data.txt" が検索されます。/bin/ ディレクトリ内に移動してそこからアプリケーションを実行すると、/bin/ ディレクトリに関連するファイルが検索されます。
私は同様の問題を抱えていました.srcフォルダー内のcobolcopybooksという名前のフォルダーにファイルを配置し、classloader.getResource( "cobolcopybooks/demostud.cob")を使用してプロジェクト内でそれらにアクセスしようとしましたが、nullポインター例外が発生していました.何度か失敗した後、ワークスペースをクリーンアップしてビルドすることで何度か試してみましたが、プロジェクトと一緒にファイルをビルドできるようにプロジェクトを更新していないことに気付きました。つまり、実行時にルート ディレクトリが bin ディレクトリになり、そこでこれらのファイルを検索するため、これらのファイルは他のクラス ファイルと一緒に表示される必要があります。
ユーザーがファイルへの完全なファイル パスを入力せず、「myfilenameonly」のようなものを入力すると仮定します。
File file = new File(".", args[0])
この場合、ファイルを見つけるために必要です (渡された最初の引数に注意してください)。
すべてのプラットフォーム:File.getParent()
親ディレクトリを返しません。「..」またはファイル システム固有の方法で親ディレクトリの名前を返す必要があります。
ファイルが配置されているディレクトリへのフル パスを指定せずにファイル "myfilenameonly" を作成すると、File.getParent()
たとえば は null を返します。
さらに参照してください: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=1228537