2016-03-25 19 views
19

コードFile file = new File("e:/");でjava.lang.Fileクラスを取得したとき、もちろんe:\ディレクトリを表すFileクラスが得られました。これはjava jdkのバグですか?

コードがFile file = new File("e:");のファイルクラスがあり、ドライブE:にある場合は、Fileクラスが現在のディレクトリを表しています。

私はディレクトリE:\ dir \にあり、このディレクトリにTest.javaという名前のファイルがあるとします。 イッツ内容は次のとおりです。

import java.io.File; 
public class Test { 
    public static void main(String[] args) { 
     File file = new File("e:"); 
     File[] files = file.listFiles(); 
     for(File f: files){ 
      System.out.println(f + " " + f.exists()); 
     } 
    } 
} 

オープンディレクトリeに移動CMDツールと:DIR \、これで次のコマンドを実行します。

E:\dir> javac Test.java 
E:\dir> java Test 

私が得た:

e:\Test.class false 
e:\Test.java false 

これはjava jdkのバグですか? @JimGarrisonから


追加情報:

私は、このコードに(私のDに住んでいる:ドライブ)Eclipseで

public class Foo3 
{ 
    public static void main(String[] args) throws Exception 
    { 
     File f = new File("D:"); 
     System.out.println(f.getCanonicalPath()); 
     for (File x : f.listFiles()) 
      System.out.println(x + " " + x.getCanonicalPath() + " " + x.getAbsolutePath() + " " + x.exists() + " " + x.getAbsoluteFile().exists()); 
    } 
} 

を実行し、次の出力を得た:

D:\dev\src\pdxep 
D:\.classpath D:\dev\src\pdxep\.classpath D:\dev\src\pdxep\.classpath false true 
D:\.project D:\dev\src\pdxep\.project D:\dev\src\pdxep\.project false true 
D:\.settings D:\dev\src\pdxep\.settings D:\dev\src\pdxep\.settings false true 
D:\gallery D:\dev\src\pdxep\gallery D:\dev\src\pdxep\gallery false true 
D:\pom.xml D:\dev\src\pdxep\pom.xml D:\dev\src\pdxep\pom.xml false true 
D:\src D:\dev\src\pdxep\src D:\dev\src\pdxep\src false true 
D:\target D:\dev\src\pdxep\target D:\dev\src\pdxep\target false true 

これは、面白いことが起こっていることを確認します。

Java Bug 8130462は、相対的な絶対パスとは具体的にはWindowsで関係しているように関連しているようです。

+1

非常に興味があります。私も問題を再現することができます。 –

+0

上記のようにプログラムを実行しましたが(クラス名をTestFileに変更しましたが)、e:ドライブ(Windows 10)の期待される出力(ファイルやディレクトリのリストなど)を受け取りました。 Java 1.8.0_72を実行しています。 @ジムガリソンそれはあなたが問題を再現興味深いです。 Eclipseとコマンドラインの両方から実行してください。違いは、私はパッケージ名を持っていたので、java -cp ./bin package.TestFile – KevinO

+0

デバッガで実行して 'println'で停止すると、パスと正規パスの間に違いがあることがわかります。表示される出力(現在のディレクトリが見つからない)は、ファイルの検索に使用されているようですが、標準パスの印刷には現在のディレクトリが含まれています。確かにバグ(Windowsファイルシステムプロバイダの実装にある可能性が高い)のように見えます。明示的な完全パス文字列からファイルを作成しても、この問題は発生しません。 –

答えて

1

コードFile file = new File("e:");で現在の作業ディレクトリを表すFileを取得することに関する最初の部分はバグではありません。 Windowsの「ドライブ相対パス」です。つまり、指定されたドライブの現在の作業ディレクトリに対する相対パス。

を(はい、Windowsはドライブごとに異なる作業ディレクターを持っている)問題は、Javaが誤ってパスが絶対パスのように見えるパスにドライブ文字の後に\を追加し、誤っおそらくfile.exists()falseを返すということですそのための。

しかし、Javaは正しくcanonical-pathとabsolute-pathを解決し、x.getAbsoluteFile().exists()で正しくtrueを返します。 Javaはまた、CWDの内容をfile.listFiles()に正しく返します。これは、あなたのサンプルコードに気付いたとおりです。

データベースの古いバグが見つかりました。これについてはJDK-5066567、それとも少なくともこれに似ています。 2004年に作成され、2013年に「In progress」に設定され、現在の譲受人が「非アクティブ」になっていますので、もしもこれがあったとしても、すぐにこれを修正する予定はありません。

質問に答えるには、私ははいと答えるでしょう、それはバグです。

ただし、java.nio.file.Pathで処理する方が良いと思われます。したがって、ユークケースではなくjava.nio.file.*パッケージを使用することができれば、それは許容される回避策かもしれません。

1

これはバグではありません。

  • E:/あなたがドライブ

  • E:はあなただけのドライブを指定する意味ディレクトリの両方を指定することを意味し、ディレクトリがデフォルト値に任されています。

注:今、人々は現在ディレクトリをどう思うか、実際にデフォルトディレクトリです。何も指定されていないときにデフォルトで適用されるもの。 ドライブをまったく指定しない場合と同じですが、デフォルト(現在のデフォルト)が適用されます。

これはほとんどのファイルシステムで動作する方法です。

+0

デフォルトのディレクトリに興味があり、これを知らなかった。あなたはこれについてもっと読むためのリンクを提供できますか?しかし、file.exists()はこれにかかわらずtrueを返さなければなりません。それはバグですので、残念ですが、その点で私はあなたが間違っていると思います。それともこの行動についての説明がありますか? – gustf

+0

「現在の作業ディレクトリ」は何十年にもわたって使用されてきた言葉です。そのため、例えば 'pwd'コマンドに' pdd'というスペルはありません。名前を変更しようとするとあまり意味はありません。 – EJP

+0

@EJPでは、なぜ昔のVMSのコマンド言語(DCLと呼ばれている)でcdコマンドが実際に 'set default'になったのかを説明することができます。そしてBTW、WindowsのチーフアーキテクトはVMSのアーキテクトでもあるDave Cuttlerだったことを思い出させる必要がありますか? –

関連する問題