web-dev-qa-db-ja.com

Java new File()はFileNotFoundExceptionを示していますが、ファイルは存在します

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

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

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

編集:それは実際にディレクトリを指していましたが、私はその問題を修正しました。 file.exists()はtrueを返しますが、スキャナーに配置しようとすると、filenotfoundexceptionがスローされます

ここにすべての私のコードがあります

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);
        }
}
31
scrblnrd3

実行時に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;キャッチするか、スローするように宣言する必要があります

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

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チェック済み例外です。つまり、例外かもしれない throwed mustのメソッドは、例外をキャッチするか、throws句で宣言するということです。上記の修正では、後者のアプローチを採用しています。

41
Terry Li

コード自体は正常に機能しています。問題は、プログラムの作業パスがあなたが考えている以外の場所を指していることです。

この行を使用して、パスの場所を確認します。

System.out.println(new File(".").getAbsoluteFile());
46
libik

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

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

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

13
petehern

私は最近、ファイルがディスク上に明らかに存在するときに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デバッガを使用して、パス名文字列を文字ごとに慎重に調べ、存在しない文字を探します。 (ホモグリフ文字も確認してください!)

6
yurin

ファイルの許可属性に応じて、ファイルの読み取りと書き込みがOSによってブロックされる可能性があります。

ファイルから読み取ろうとしている場合は、FileのsetReadableメソッドを使用してtrueに設定することをお勧めします。

String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file;
File f = new File(arbitrary_path);
f.setReadable(true);
data_of_file = Files.readAllBytes(f);
f.setReadable(false); // do this if you want to prevent un-knowledgeable 
                      //programmers from accessing your file.

ファイルに書き込もうとしている場合は、FileのsetWritableメソッドを使用してtrueに設定することをお勧めします。

String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
File f = new File(arbitrary_path);
f.setWritable(true);
Files.write(f, byte_array);
f.setWritable(false); // do this if you want to prevent un-knowledgeable 
                      //programmers from changing your file (for security.)
3
Solumyr

私のために働いた簡単な修正は、srcからプロジェクトのメインフォルダにファイルを移動することです。これは最善の解決策ではありませんが、プロジェクトの規模と時間によっては、完璧な場合があります。

3
Irina Larisa

ここで言及した他のすべての答えとは別に、あなたは私のために働いた1つのことをすることができます。

スキャナーまたはコマンドライン引数を使用してパスを読み取る場合は、Windowsエクスプローラーから直接パスをコピーして貼り付けるのではなく、単にパスを手動で入力してください

それは私のために働いた、それが誰かを助けることを願っています:)

2
Alok

この同じエラーが発生し、Javaプロジェクト構造にあるsrcディレクトリを追加するだけで解決しました。

String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
File file = new File(path);
Scanner scanner = new Scanner(file);

System.getProperty( "user.dir")およびnew File( "。")。getAbsolutePath()はプロジェクトのルートディレクトリパスを返すため、サブディレクトリとパッケージにパスを追加する必要があることに注意してください。

0
lewiscool