46

コンピューター サイエンス クラスの課題があり、いくつかのテスト スコアを含むファイルを読み取り、それらの合計と平均を求められます。合計と平均化は簡単ですが、ファイルの読み取りに問題があります。インストラクターはこの構文を使用するように言いました

Scanner scores = new Scanner(new File("scores.dat"));

ただし、これは をスローしFileNotFoundExceptionますが、ファイルが現在のフォルダーに存在するかどうかを何度も確認した後、アクセス許可で何かを行う必要があることがわかりました。全員の読み取りと書き込みのアクセス許可を変更しましたが、それでも機能せず、エラーがスローされ続けます。なぜこれが起こっているのか、誰にも分かりますか?

編集:実際にはディレクトリを指していましたが、その問題を修正しました。今は をfile.exists()返しますtrueが、 に入れようとするとScannerFileNotFoundException

これが私のすべてのコードです

import java.util.Scanner;
import java.io.*;
public class readInt{
        public static void main(String args[]){
                File file = new File("lines.txt");
                System.out.println(file.exists());
                Scanner scan = new Scanner(file);
        }
}
4

11 に答える 11

78

FileNotFoundException実行時に がスローされる状況がいくつかあります。

  1. 指定されたファイルは存在しません。これには、次のようなさまざまな理由が考えられます。

    • パス名が単に間違っている
    • パス名は正しいように見えますが、気付かなかった非印刷文字 (またはホモグリフ) が含まれているため、実際には間違っています。
    • パス名は相対パスであり、実行中のアプリケーションの実際の現在のディレクトリに対して正しく解決されません。これは通常、アプリケーションの現在のディレクトリが期待または想定したものではないために発生します。
    • ファイルへのパスが壊れています。たとえば、パスのディレクトリ名が間違っている、パスのシンボリック リンクが壊れている、またはパス コンポーネントの 1 つに権限の問題があるなどです。
  2. 名前付きファイルは、実際にはディレクトリです。

  3. 指定されたファイルは、何らかの理由で読み取り用に開くことができません。

良いニュースは、問題は必然的に上記のいずれかになるということです。それは、どれを解決するかの問題です。以下のことを試すことができます。

  • を呼び出すfile.exists()と、指定された名前/パス名を持つファイル システム オブジェクトが存在するかどうかがわかります。

  • 呼び出すfile.isDirectory()と、ディレクトリであるかどうかがテストされます。

  • 呼び出すfile.canRead()と、読み取り可能なファイルかどうかがテストされます。

  • この行は、現在のディレクトリが何であるかを示します。

      System.out.println(new File(".").getAbsolutePath());
    
  • この行は、予期しない先頭または末尾の空白などを見つけやすくする方法でパス名を出力します。

      System.out.println("The path is '" + path + "'");
    

    出力で予期しないスペース、改行などを探します。


サンプル コードにコンパイル エラーがあることがわかりました。

Netbeans からの苦情に対処せずにコードを実行したところ、次の例外メッセージが表示されました。

スレッド「メイン」での例外 java.lang.RuntimeException: コンパイルできないソース コード - 報告されていない例外 java.io.FileNotFoundException; キャッチするか、投げることを宣言する必要があります

コードを次のように変更すると、その問題が修正されます。

public static void main(String[] args) throws FileNotFoundException {    
    File file = new File("scores.dat");
    System.out.println(file.exists());
    Scanner scan = new Scanner(file);
}

説明:コンストラクターは、例外Scanner(File)をスローするものとして宣言されています。FileNotFoundException(スキャナーがファイルを開くことができない場合があります。) 現在FileNotFoundExceptionは、チェック済みの例外です。つまり、例外スローされる可能性のあるメソッドは、例外をキャッチするか、句で宣言する必要があります。throws上記の修正は、後者のアプローチを採用しています。

于 2013-10-11T02:12:16.593 に答える
18

明らかに多くの考えられる原因があり、以前の回答はそれらを十分に文書化していますが、特定のケースでこれをどのように解決したかを次に示します。

私の学生はこの問題を抱えていて、それを理解しようとして髪を引き裂きそうになりました. ファイルが存在するように見えても、存在しないことが判明しました。問題は、Windows 7 が「既知のファイル タイプのファイル拡張子を非表示にする」ように構成されていたことです。これは、ファイルの名前が「data.txt」のように見える場合、実際のファイル名は「data.txt.txt」であることを意味します。

これが他の人が髪を節約するのに役立つことを願っています.

于 2015-05-08T02:18:31.557 に答える
10

最近、ファイルが明らかにディスク上に存在する場合に FileNotFoundExeption を生成する興味深いケースを見つけました。私のプログラムでは、別のテキスト ファイルからファイル パスを読み取り、File オブジェクトを作成します。

//String path was read from file
System.out.println(path); //file with exactly same visible path exists on disk
File file = new File(path); 
System.out.println(file.exists());  //false
System.out.println(file.canRead());  //false
FileInputStream fis = new FileInputStream(file);  // FileNotFoundExeption 

この問題の原因は、パス\r\nの末尾に非表示の文字が含まれていたことです。

私の場合の修正は次のとおりです。

File file = new File(path.trim()); 

少し一般化すると、非表示/非印刷文字にはスペースまたはタブ文字が含まれている可能性があり、パスの先頭、末尾、またはパスに埋め込まれている可能性があります。一部のケースではトリムが機能しますが、すべてではありません。この種の問題を見つけるのに役立つことがいくつかあります。

  1. パス名を引用符で囲んで出力します。例えば

      System.out.println("Check me! '" + path + "'");
    

    スペースや改行がないか出力を注意深く確認してください。

  2. Java デバッガーを使用して、パス名の文字列を 1 文字ずつ注意深く調べ、存在しないはずの文字を探します。(ホモグリフ文字もチェックしてください!)

于 2016-08-11T07:55:03.430 に答える