Java 文件选择器GUI选择和键入文件名之间的差异
我有一个使用JFileChooser选择目录的应用程序。在这个应用程序中,我不想尝试处理符号链接,我想在多个平台上运行。因此,代码尝试确定所选文件是否为符号链接,如果是,则显示错误对话框 以下是从JFileChooser获取文件的代码Java 文件选择器GUI选择和键入文件名之间的差异,java,swing,jfilechooser,Java,Swing,Jfilechooser,我有一个使用JFileChooser选择目录的应用程序。在这个应用程序中,我不想尝试处理符号链接,我想在多个平台上运行。因此,代码尝试确定所选文件是否为符号链接,如果是,则显示错误对话框 以下是从JFileChooser获取文件的代码 public File getDirectoryChoice(String buttonText, String currentDirectory) { File chosenFile = null; if (fileChooser == null) {
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;
}
下面是我用来确定所选文件是否为符号链接的代码:
public static boolean isSymbolic(File f)
{
try
{
String absolute = f.getAbsolutePath();
String canonical = f.getCanonicalPath();
return !(absolute.equals(canonical));
}
catch (IOException ioe)
{
return false;
}
}
在Windows7上:如果用户使用鼠标选择一个给定的目录,这可以正常工作。如果用户在“文件名”文本框中键入相同的目录名,则第二个代码段指示绝对路径和规范路径不相同。用户是否输入尾随的反斜杠并不重要
当我在“return”语句行的调试器中停止此操作并查看这两个字符串的详细信息时,绝对路径字符串的哈希值是一个很大的负数,而规范字符串的哈希值是0。我不知道为什么会这样,事实上我想知道这是否是(eclipse)调试器的一个怪癖
有人能告诉我为什么会有这种差异吗?请仔细检查键入的字符串是否与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;
}
我试了一下,没想到就输入了c:\temp
。就像在测试中一样,isSymbolic()
方法返回true
。然而,仔细检查后,我注意到,当我在文件选择器中选择此路径时,它返回了C:\temp
(注意大写字母C
)
因此,即使它很难看,您也可以添加一个特殊情况,例如:
if (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0)
return !(absolute.equalsIgnoreCase(canonical));
else
return !(absolute.equals(canonical));
您可能还想看看这个相关的问题:“”。这里有很多答案,您可能会觉得很有帮助。如果将
absolute.hashCode()
和canonical.hashCode()
添加到Eclipe的表达式窗口中,您应该会看到正确的值-两者都不是零。字符串具有初始化为0的哈希
成员。然后,当执行hashCode()
时,它被更新为正确的值
因此,您可能看到的是绝对
字符串的计算哈希和规范
字符串的尚未计算哈希
在String.hashCode()
中放置一个断点,您将看到Windows上的getCanonicalPath()
触发器absolute.hashCode()
。在Windows上实现getCanonicalPath()
似乎会缓存规范化的结果。在WinNTFileSystem.canonicalize()
之间的某个地方,缓存结果映射中的查找会触发absolute.hashCode()
因此,在isSymbolic()
中对return
语句设置的断点处,absolute
有一个有效的哈希代码,canonical
仍为零
下面是堆栈跟踪,它演示了作为f.getCanonicalPath()
执行的绝对.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
String.hashCode()行:1482[局部变量不可用]
ExpiringCache$1(HashMap).getEntry(对象)行:344
ExpiringCache$1(LinkedHashMap).get(对象)行:280
ExpiringCache.entryFor(字符串)行:83
ExpiringCache.get(字符串)行:58
WinNTFileSystem(Win32文件系统)。规范化(字符串)行:377
File.getCanonicalPath()行:559
Test.isSymbolic(文件)行:25
测试。主(字符串[])行:16
Capital C——不管你有多少经验,你仍然会被它抓住(显然)。