2012-04-23 5 views
4

私はJFileChooserを使ってディレクトリを選択するアプリケーションを持っています。このアプリケーションでは、シンボリックリンクを処理しようとは思わないし、複数のプラットフォームで実行したいと考えています。したがって、コードは選択されたファイルがシンボリックリンクであるかどうかを判断し、そうであればエラーダイアログを表示します。FileChooserはGUIの選択と入力ファイル名の間で差をつけます

ここでは、JFileChooserからファイルを取得するコードを示します。

public File getDirectoryChoice(String buttonText, String currentDirectory) 
{ 
    File chosenFile = null; 
    if (fileChooser == null) { fileChooser = new JFileChooser(); } 
    if (currentDirectory != null) 
    { fileChooser.setCurrentDirectory(new File(currentDirectory)); } 
    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
    fileChooser.setApproveButtonText(buttonText); 
    int returnValue = fileChooser.showOpenDialog(mainFrame); 
    if (returnValue == JFileChooser.APPROVE_OPTION) 
    { 
    chosenFile = fileChooser.getSelectedFile(); 
    } 
    return chosenFile; 
} 

と、ここで私が選択したファイルがシンボリックリンクであるかどうかを判断するために使用するコードです:Windows 7の上で

public static boolean isSymbolic(File f) 
{ 
    try 
    { 
    String absolute = f.getAbsolutePath(); 
    String canonical = f.getCanonicalPath(); 
    return !(absolute.equals(canonical)); 
    } 
    catch (IOException ioe) 
    { 
    return false; 
    } 
} 

:ユーザーがマウスを使用して、指定されたディレクトリを選択した場合、これが正常に動作します。ユーザーが同じディレクトリ名をファイル名テキストボックスに入力すると、2番目のコードスニペットは、絶対パスと正規パスが同じでないことを示します。ユーザーが末尾のバックスラッシュを入力したかどうかは関係ありません。

'return'ステートメント行のデバッガでこれを停止し、2つの文字列の詳細を調べると、絶対パス文字列のハッシュ値は大きな負数になり、正規文字列のハッシュ値私はそれがなぜ起こるのか分からず、実際には(Eclipse)デバッガの奇妙なものかもしれません。

この違いがある理由を教えてもらえますか?

答えて

2

という文字列を、正確にとJFileChooserが返す文字列と同じように入力していることを再度確認します。

私はこれを試しましたが、私はc:\tempとタイプしました。あなたのテストのように、isSymbolic()メソッドはtrueを返しました。しかし、詳しい点検の結果、ファイル選択でこのパスを選択すると、代わりにC:\tempが返されたことに気付きました(大文字のCに注意してください)。

それは醜いだにもかかわらずだから、あなたはこのような何か特別なケースを追加することができます。「Java 1.6 - determine symbolic links」:

if (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) 
     return !(absolute.equalsIgnoreCase(canonical)); 
    else 
     return !(absolute.equals(canonical)); 

また、この関連の質問を見てみたいことがあります。そこにあなたが役に立つかもしれないかなりの答えがあります。

+0

資本Cを - あなたが持っているどのくらいの経験は関係ありません、あなたはまだ(明らかに)ことによって捕まることができます。 – arcy

1

EclipeのExpressionsウィンドウにabsolute.hashCode()canonical.hashCode()を追加すると、正しい値(ゼロでない値)が表示されます。文字列にはhashのメンバーがあり、0に初期化されます。hashCode()が実行されると、正しい値に更新されます。

だから、おそらくabsolute文字列の計算されたハッシュとcanonical文字列の計算されたハッシュは表示されません。

String.hashCode()にブレークポイントを設定すると、WindowsでgetCanonicalPath()がトリガーabsolute.hashCode()と表示されます。 Windows上でのgetCanonicalPath()の実装では、正規化の結果がキャッシュされているようです。 WinNTFileSystem.canonicalize()のどこかに、キャッシュされた結果マップの参照がabsolute.hashCode()をトリガーします。

だから、あなたがisSymbolic()return声明に設定することをブレークポイントで、absoluteは、有効なハッシュコードを持っており、canonicalはゼロとしてまだそれを持っています。ここで

f.getCanonicalPath()の結果としてabsolute.hashCode()実行実証スタックトレースです:

String.hashCode() line: 1482 [local variables unavailable] 
ExpiringCache$1(HashMap<K,V>).getEntry(Object) line: 344  
ExpiringCache$1(LinkedHashMap<K,V>).get(Object) line: 280 
ExpiringCache.entryFor(String) line: 83 
ExpiringCache.get(String) line: 58 
WinNTFileSystem(Win32FileSystem).canonicalize(String) line: 377 
File.getCanonicalPath() line: 559 
Test.isSymbolic(File) line: 25 
Test.main(String[]) line: 16 
+0

かなり、チップのおかげで正しい。 – arcy

関連する問題