Java:如何确定文件所在的驱动器类型?

Posted

技术标签:

【中文标题】Java:如何确定文件所在的驱动器类型?【英文标题】:Java: how to determine the type of drive a file is located on? 【发布时间】:2012-02-06 16:43:32 【问题描述】:

Java 是否有一种独立于平台的方法来检测文件所在的驱动器类型?基本上我有兴趣区分:硬盘可移动驱动器(如 U 盘)和网络共享。 JNI/JNA 解决方案不会有帮助。可以假定为 Java 7。

【问题讨论】:

也许解决你为什么想知道这个可能更简单? 我需要这些信息来警告用户底层文件系统的某些缺陷:性能、文件系统监控不起作用,诸如此类。 请参阅***.com/questions/3542018/… 我正在使用 WMI 访问所需的信息。 【参考方案1】:

您可以使用 Java 执行 cmd:

fsutil fsinfo drivetype drive letter

结果会是这样的:

C: - Fixed Drive
D: - CD-ROM Drive
E: - Removable Drive
P: - Remote/Network Drive

【讨论】:

它不是独立于平台的,fsutil 甚至似乎需要管理权限。 我发现这段代码很有帮助:***.com/questions/10678363/… 我也是(非常有帮助)【参考方案2】:

Swing 中的FileSystemView 类具有一些 功能来支持检测驱动器的类型(参见isFloppyDriveisComputerNode)。恐怕没有标准的方法来检测驱动器是否通过 USB 连接。

人为的、未经测试的例子:

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
....
JFileChooser fc = new JFileChooser();
FileSystemView fsv = fc.getFileSystemView();
if (fsv.isFloppyDrive(new File("A:"))) // is A: a floppy drive? 

在 JDK 7 中还有另一个选项。我没用过,但是FileStore API 有一个type 方法。 documentation 表示:

此方法返回的字符串格式是高度特定于实现的。例如,它可能指示使用的格式或文件存储是本地还是远程。

显然使用它的方式是这样的:

import java.nio.*;
....
for (FileStore store: FileSystems.getDefault().getFileStores()) 
    System.out.printf("%s: %s%n", store.name(), store.type());
 

【讨论】:

FileSystemView.isFloppyDrive() 是由类似 "path.equals("A:\\")" 之类的东西实现的,不幸的是它没有帮助。另外,我没有发现 FileStore.type() 有帮助。它为我的网络共享返回“NTFS”。 FileStore#type() 在 Windows 7、Java 7 上为网络驱动器返回“NTFS”。 FileStore#type() 也为 Windows 10 上的本地硬盘返回“NTFS”。【参考方案3】:

这里有一个要点,它展示了如何使用net use 来确定这一点:https://gist.github.com/digulla/31eed31c7ead29ffc7a30aaf87131def

代码中最重要的部分:

    public boolean isDangerous(File file) 
        if (!IS_WINDOWS) 
            return false;
        

        // Make sure the file is absolute
        file = file.getAbsoluteFile();
        String path = file.getPath();
//        System.out.println("Checking [" + path + "]");

        // UNC paths are dangerous
        if (path.startsWith("//")
            || path.startsWith("\\\\")) 
            // We might want to check for \\localhost or \\127.0.0.1 which would be OK, too
            return true;
        

        String driveLetter = path.substring(0, 1);
        String colon = path.substring(1, 2);
        if (!":".equals(colon)) 
            throw new IllegalArgumentException("Expected 'X:': " + path);
        

        return isNetworkDrive(driveLetter);
    

    /** Use the command <code>net</code> to determine what this drive is.
     * <code>net use</code> will return an error for anything which isn't a share.
     * 
     *  <p>Another option would be <code>fsinfo</code> but my gut feeling is that
     *  <code>net</code> should be available and on the path on every installation
     *  of Windows.
     */
    private boolean isNetworkDrive(String driveLetter) 
        List<String> cmd = Arrays.asList("cmd", "/c", "net", "use", driveLetter + ":");

        try 
            Process p = new ProcessBuilder(cmd)
                .redirectErrorStream(true)
                .start();

            p.getOutputStream().close();

            StringBuilder consoleOutput = new StringBuilder();

            String line;
            try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) 
                while ((line = in.readLine()) != null) 
                    consoleOutput.append(line).append("\r\n");
                
            

            int rc = p.waitFor();
//            System.out.println(consoleOutput);
//            System.out.println("rc=" + rc);
            return rc == 0;
         catch(Exception e) 
            throw new IllegalStateException("Unable to run 'net use' on " + driveLetter, e);
        
    

【讨论】:

【参考方案4】:

看看这个讨论:How can I get list of all drives but also get the corresponding drive type (removable,local disk, or cd-rom,dvd-rom... etc)?

特别关注http://docs.oracle.com/javase/1.5.0/docs/api/javax/swing/filechooser/FileSystemView.html

我个人没有使用过这个,但它似乎相关。它的方法类似于isFloppyDrive

也可以关注JSmooth

【讨论】:

FileSystemView 不起作用。 JSmooth 可能会起作用,尽管我希望找到一些 JRE 本身附带的 API。

以上是关于Java:如何确定文件所在的驱动器类型?的主要内容,如果未能解决你的问题,请参考以下文章

实现一个中断驱动的采样分析器

如何确定映射驱动器的实际路径?

Linux驱动之内核加载模块过程分析

perl 脚本来搜索 java 源代码中区分大小写的文件名

错误 - 无法确定数据库类型 NONE 的嵌入式数据库驱动程序类

如何运用领域驱动设计 - 实体