ファイルが存在する場合、File.exists()はfalseを返します


90

背後にロジックが見つからないようなバグに遭遇しました。次のように作成されたこのFileオブジェクトがあります。

File file = new File("utilities/data/someTextFile.txt");

次にを実行file.exists()すると、戻りますfalse(!?)。ファイルが見つからない場合は、ファイルにログf.getAbsolutePath()を記録しています。パスを見ると大丈夫そうです。Windowsの[実行]ウィンドウに完全なパスをコピーして貼り付けると、ファイルが正常に開きます。

ファイルは常に存在し、アプリケーションの実行中に削除も変更もされません。ローカルマシンにあります。

これは特定の状況でのみ発生するようです。障害はいつでも再現できますが、ファイルオブジェクトのパスは、障害を再現するために行ったアクションによって変更されていないと確信しています。

file.exists()falseを返す原因は何ですか?これは、アクセス許可やファイルロックなどと関係がありますか?


では、exists()がfalseを返してもファイルから読み取ることはできますか?
ハリーライム

はい、exists()がfalseを返してもファイルから読み取ることができます。
atsjoo 2009年

1
障害を再現するために正確に何が必要ですか?
user85421 2009年

1
これは、MATLABで記述され、Javaアプリケーションにコンパイルされた関数を呼び出すアプリケーション内にあります。「現在のディレクトリ」を変更するmatlab関数が問題を引き起こしているようです。私はファイルオブジェクトを作成するときに絶対パスを使用しているので、これは問題にはならないはずですが、問題があるようです。もちろん、ファイルオブジェクトの絶対パスを確認しましたが、それは正しいです(matlab関数が現在のディレクトリを変更する前と同じです)。
atsjoo 2009年

7
リモートディレクトリ(NFSマウントなど)に対して作業していませんか?
Tomer Gabel、

回答:


42

Windows 7で次の状況が発生しています。

file.exists() == false
file.getAbsoluteFile().exists() == true

問題のファイルは「var \ log」です。絶対パスは、通常のサブディレクトリ(仮想ストアではない)にある既存のファイルを参照します。これはIDEから見られます。


16
私はそれを理解しました:bugs.sun.com/bugdatabase/view_bug.do; : YfiG?bug_id=4483097 どうやら、ファイルで実行されている操作は現在のディレクトリに対して解決されますが、getAbsolutePathはuser.dirに対して解決されます。これら2つのパスが一致しない場合、競合する結果になります。悪魔!
Roman Zenka

3
ファイルが存在するかどうかを確認するために両方の方法を使用しようとしたまったく同じ問題がありますが、それでもWindows 7でのみfalseが発生します!何か案が?
Dejell

@Odelya:どのIDEを使用していますか?-Duser.dirは何に設定されていますか?私の問題は、-Duser.dirを現在動作しているディレクトリとは異なるディレクトリに設定したことが原因です。
Roman Zenka

1
動的Webプロジェクトで作業している場合は、file.exists()を使用すると例外がスローされます。file.getAbsoluteFile()。exists()を使用して、WEB-INFディレクトリ内のファイルを確認します(Windows 7固有ではなく、一般的なヒント) )。
PS

この回答とコメントに個別のQAを作成することを検討してください
Bato-Bair Tsyrenov '26

17

Javaでのパスの指定方法に違いがあるようです。

たとえば、ファイルパスが次のように指定されているfile:/C:/DEV/test.txt場合

File f = new File(filename);
f.exists();

戻りfalseます。パスは、エクスプローラまたはブラウザで機能する可能性がありますが、これはURLであり、絶対ファイルパスではありません。

しかし、一方で、ファイルパスが次のように指定されているC:/DEV/test.txt場合

File f = new File(filename);
f.exists();

trueパスはURLではないので戻りますが、絶対パスです。

春のフレームワークを正確に何であるResourceUtils.getFile(filename)名前はURLまたは絶対ファイルパスのいずれかであることができる場所-ありません。


5
file:/C:/DEV/test.txtパス名として機能するとは思いません。パス名ではなくURLです。一部の人々はこの間違いを犯しますが、OPが持っているという証拠はありません...
スティーブンC

15

プロセスにファイルが存在するかどうかを通知する権限がない場合は、falseを返します。ファイルを開くことは可能かもしれませんが、それが存在するかどうかは通常の方法ではわかりません。


20
面白い。これを拡張できますか?どの特定の権限を念頭に置いていますか?
クレマン

これは、ファイル/ディレクトリの存在に到達するためのjava.nio.file.AccessDeniedExceptionのブロック機能です。たとえば、FARまたは他のファイルエクスプローラーでdirを開いたままにして、ネストされたすべてのファイルでdirを削除し、このdirの存在を確認すると、一時ファイルが保持されているAccessDeniedException(IOExceptionを拡張)を取得できます。この場合、Files.existsはIOExceptionに対してfalseを返します。
beluha

11

上記の答えは私の場合助けにはなりませんでした。上記のように、私は持っていました:

file.exists() => false
file.getAbsoluteFile().exists => true

これの根本的な原因は、Windows 7マシンの所有者がCMDのレジストリを変更して、コマンドを自動実行して特定のディレクトリで起動し、Pythonで動作するようにすることでした。この変更により、Windowsなどの特定のファイル操作にCMDを使用するJava 1.6コードが機能しなくなりました。レジストリから自動実行を排除することで問題は解決しました。exists()


1
3.5年後、私は同じ問題に遭遇しました。cmd.comを起動するたびに環境変数を構成するように自動実行スクリプトを設定しました。現在のディレクトリも変更されませんでした。いくつかのdoskeyマクロといくつかの環境変数だけです。自動実行を削除し、ファイル内のコマンドを手動で実行したところ、突然File.exists()が正しく機能しました。
Homr Zodyssey 2016年

1
OMG、それは本当に(両方とも)機能します。間違ったファイルを簡単にチェックしていて、この質問に出くわして、なぜそれらがどれも機能しない理由を見つけました:)ところで、()2行目ではexists、 )
RAM237 2017

3

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

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

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


私の場合、これは問題ではなかったと思います。私の質問で述べたように、「完全なパスをWindowsの[ファイル名を指定して実行]ウィンドウにコピーして貼り付けることができ、ファイルは正常に開きます。」ということは、ファイルが実際に存在することを意味します。
atsjoo

3

new Fileコマンドは、ただ与えられたパス名を使用してファイルのインスタンスを作成します。実際にはハードドライブにファイルを作成しません。

あなたが言うなら

File file = new File ("path");
file.exists() 

これは、同じパスを持つ既存のファイルが存在する場合にのみtrueを返すことができます。最初の行で宣言された同じファイルをチェックするつもりなら、この方法で使用する必要があるかもしれません。

File file = new File ("path");
file.createNewFile();
file.exists();

これでtrueが返されます。


簡単な説明:newキーワードを使用してコンストラクターを呼び出すたびにオブジェクトが作成されます-この場合と同じですが、名前がFileであるクラスによって記述されたオブジェクト!したがって、File!=記述子のインスタンスではありません:)
ceph3us 2016年

3

メソッドを呼び出さなければならないたびにgetAbsoluteFile()呼び出しを処理したくない場合は、絶対パスを使用してファイルインスタンスを作成することをお勧めします。これでうまくいくはずです:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

私はそれをtry-catchブロック、BTWで囲むことをお勧めします。


3

この問題を一般化するには、URL / URIをローカルパスに変換するときに問題が発生します。

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

お役に立てれば。


2

[「既知のファイルタイプの拡張子を隠す」]がチェックされている場合、[エクスプローラ] / [実行ウィンドウ]に「t.txt」と入力すると、ウィンドウは「t.txt.txt」を開きますが、プログラムでは開きません。


1
この問題があり、C:\ testに「testFile.txt」と呼ばれるtxtファイルを作成したことが問題でした。パスC:\ test \ testFile.txtを使用してこのファイルを参照しましたが、機能しませんでした。これは、ファイルが実際にtestFile.txt.txtとして保存されていたため、上記の解決策に賛成票を投じました(古い質問ですが、回答は受け付けられません!)
Theblacknight

神様、ウィンドウズはすごい。
aafc 2014年

0

みんな良い反応。これは、Java C:がWindowsのルートディレクトリにアクセスする際の問題のようです。他のディレクトリは細かいことが、いくつかの理由で、特に言及すべきであるC:\か、C:またはC:/エラーを与えるかもしれません。への言及をトラップnew File("C:");して新しいものに置き換えることで、この非常に類似した問題を解決しましたFile(System.getProperty("file.separator"));しました。そうしないと、ファイルディレクトリとして「c:」と言う代わりに「\」をハードコードでき、うまくいく場合があります。エレガントではありませんが、このプロジェクトで私のために仕事を成し遂げました。

お役に立てば幸いです。正しい解決策ではないかもしれませんが、少なくともそれは私にとってはうまくいきました。私は〜に乗っていますJRE 1.6, Win 7ます。乾杯!

敬具、

ゆうたろう


0

失敗する状況が別のユーザーとしての実行に関係していて、Windows Vista / Windows 7を使用している場合は、VirtualStoreが原因である可能性があります。これは、Windowsが非特権ユーザーに「書き込み」場所を許可するメカニズムでは、通常はできません。ただし、変更は「%USERPROFILE%\ AppData \ Local \ VirtualStore \」に保存されます。これは、各ユーザーアカウントにプライベートです。


1
私はwindows xp x86で実行しています
atsjoo 2009年

0

上から何もうまくいかなかったとき、私は試しました

filePath = filePath.trim();

これにより、不要な文字から文字列が削除されます


0

最近、同じ問題に遭遇しました。私が行ったことは、Netbeansをアンインストールし、Cドライブからnetbeansフォルダーを削除し、プログラムファイル、更新、programDataを事実上すべての場所で削除することでした。その後、再インストールします。現在は正常に動作しています。上記のアクションを実行する前に、netbeansプロジェクトフォルダをバックアップすることを忘れないでください。

それが役に立てば幸い。


0

一部のIDE(多分)や一部のOS(例:ウィンドウ)では、デフォルトでファイルへの書き込みアクセス権がありません。したがって、file.exists()を実行しようとすると、falseが表示されます。これを修正するには、以下のようにします

Fileのref変数がfの場合、例:File f = new File( "path");

機能させるには、マウスでfを選択し、[検索]メニュー> [書き込みアクセス]> [ワークスペース]に移動します。うまくいけばうまくいくでしょう。


-2

次のように、代わりにバックスラッシュを使用する必要があると思います。

ファイルfile = new File( "C:\\ User \\ utilities \\ data \\ someTextFile.txt"); (タイプミスではなく、2つのバックスラッシュ)

問題を解決する必要があります:)


3
問題は、絶対パスと相対パスのどちらかに関連していると思います。スラッシュは、WindowsパスでもJavaで有効です。
рüффп
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.