web-dev-qa-db-ja.com

NIO 'Files'クラスの 'Files.exists'がfalseを返すのに、 'File.exists'がtrueを返すのはなぜですか

ファイルがネットワークフォルダに存在するかどうかを確認しようとしています。

_// File name is "\\QWERTY\folder\dir\A123456.TXT"
Path path = Paths.get("\\\\QWERTY\\folder\\dir\\A123456.TXT")
_

NIOの使用Files

_Files.exists(path) == false
_

Fileの使用:

_path.toFile().exists() == true
_

私たちのテストによると、Fileを使用するのが正しいようです。 FileFilesよりもうまく機能するのはなぜですか?

それで、それはどれですか?両方になることはできません!

しかし、待ってください、Files.notExists(path)もあります。

ネットワーク共有ファイルが実際に存在する場合

_Files.exists(path): false
Files.notExists(path): false
path.toFile().exists(): true
_

ネットワーク共有ファイルが実際に存在する場合存在しない存在する

_Files.exists(path): false
Files.notExists(path): true
path.toFile().exists(): false
_

上記の3つの結果を見る別の同様に非常識な方法

_boolean exists = Files.exists(path) || !Files.notExists(path)
boolean notExists = Files.notExists(path) || !Files.exists(path)
boolean oldFashionedExists = path.toFile().exists()
_

:笑顔:

環境とコメント

プログラムは、Windows 8.1 Pro 32ビットマシン(OSおよびマシン)で実行され、Windows 2008 R2(32ビット)マシンからネットワーク共有をチェックします。

Files.existsが失敗したことを確認するために、WatchServiceをインストールしてフォルダーを監視し、Files.existsがチェックしているときにファイルが存在することを確認しました。次に、両方のメソッドとしてログインし、File.existsが正しいものであることを確認しました。

今、私のコードでは、Files.exists(path) || path.toFile().exists()としてチェックしています。

ちょっと、両方をしなければならないのはばかげているようです。恐らく後者でうまくいくでしょう。オラクルのエンジニアに疑いの恩恵を与えようとするだけですが、全体としては、彼らが異なることを報告するのはかなりばかげています。

また、「exists」がすぐに古くてもかまいません。チェックしている瞬間にファイルが存在するかどうかを知りたいだけです。私はこれに出くわしたことがありません-私と別の開発者の間で30時間費やして、この「機能」のためにプログラムがインターフェイスしない理由を理解しようとしました。

しばらく瞑想してください

File.exists():trueを返しますこの抽象パス名が示すファイルまたはディレクトリが存在する場合に限り;それ以外の場合はfalse。

Files.exists():ファイルが存在する場合はtrueを返します。ファイルが存在しない場合はfalse またはその存在を判別できない場合

それは私をクラックします! 「この抽象パス名が示すファイルまたはディレクトリが存在する場合のみ。それ以外の場合はfalse」は、「ファイルが存在する場合はtrue、ファイルが存在しないか存在を判別できない場合はfalse」と矛盾します

それでは、「存在を判別できない」場合、_File.exists_はどのようにしてtrueになるのでしょうか。明らかに、存在はファイルによって決定できますが、ファイルによっては決定できません。

15
The Coordinator

2つの間に違いがある理由については、ドキュメントを対比してください。

File.exists():この抽象パス名で示されるファイルまたはディレクトリが存在する場合にのみtrueを返します。それ以外の場合はfalse。

Files.exists():ファイルが存在する場合はtrueを返します。ファイルが存在しない場合はfalseまたはファイルの存在を判別できません。

それはおそらく2つの違いを説明する可能性があります。おそらく、Filesはファイルの存在を確認するのに問題があります。

たとえば、Linuxでは、存在するファイルを開くことはできるが、存在することはseeできないように、ディレクトリとファイルのアクセス許可を設定することができます(ファイルのアクセス許可をより開いたままにして、ファイルが存在するディレクトリの読み取りアクセス許可を削除します)。

Oracleのドキュメントの詳細 のとおり、Files.exists()は、ファイルが存在することが確認された場合にのみtrueを返します。

falseの戻り値はnotは存在しないことを意味します。

exists()notExists()の両方を使用して、次のような3つの可能性をカバーすることをお勧めします。

if (Files.exists(fspec)) {
    System.out.println("It exists!");
else if (Files.notExists(fspec)) {
    System.out.println("It does not exist!");
else
    System.out.println("I have no idea!");

これは、上記のリンクでカバーされているファイル状態の3つの可能性をカバーしています。

  • ファイルが存在することが確認されます。
  • ファイルが存在しないことが確認されました。
  • ファイルのステータスは不明です。この結果は、プログラムがファイルにアクセスできない場合に発生する可能性があります。
6
paxdiablo

私は同じ問題を抱えていましたが、あなたのハックは私を助けませんでした。ファイルが実際に存在する場合、すべてのメソッドが私にfalseを返しました:

Files.exists(path) = false, 
path.toFile().exists() = false, 
Files.notExists(path) = true, 
Files.exists(path) || path.toFile().exists() = false

しかし、この時点でエクスプローラーでこのファイルを含むネットワークディレクトリが開かれた場合、その存在は正しく処理されました

私はディレクトリに新しいファイルを作成することでこの問題を解決しました(そしてそれを削除します):

Files.createFile(Paths.get(path.getParent().toString(), "test"));

そのコマンドの後、どうやら、Windowsはフォルダに関する情報を更新します