在Java中查找总磁盘大小的便携方式(java 6之前版本)

时间:2009-07-15 10:39:06

标签: java

我需要在Java 5(或1.5,无论如何)中找到驱动器的总大小。我知道Java 6在java.io.File中有一个新方法,但我需要它在Java 5中工作。

Apache Commons IO有org.apache.commons.io.FileSystemUtils提供 free 磁盘空间,但不提供总磁盘空间。

我意识到这是依赖于操作系统的,需要依赖凌乱的命令行调用。我很喜欢它在“大多数”系统上工作,即windows / linux / macosx。我最好使用现有的库而不是编写自己的变体。

有什么想法?感谢。

3 个答案:

答案 0 :(得分:4)

更新

我为误读这个问题道歉,我建议复制FileSystemUtils方法,但修改它稍微运行的命令。

在dos中,您可以使用fsutil命令获取空闲和总字节数:

fsutil volume diskfree [drive letter]

在我的方框中,这给出了以下结果:

Total # of free bytes        : 41707524096
Total # of bytes             : 80023715840
Total # of avail free bytes  : 41707524096

在Unix上,命令仍然是“df -k”,你只对“Free”左边的“1024-blocks”列感兴趣(以下来自维基百科的例子)。你显然需要将结果乘以1024。

Filesystem    1024-blocks      Free %Used    Iused %Iused Mounted on
/dev/hd4            32768     16016   52%     2271    14% /
/dev/hd2          4587520   1889420   59%    37791     4% /usr
/dev/hd9var         65536     12032   82%      518     4% /var
/dev/hd3           819200    637832   23%     1829     1% /tmp
/dev/hd1           524288    395848   25%      421     1% /home
/proc                   -         -    -         -     -  /proc
/dev/hd10opt        65536     26004   61%      654     4% /opt

假设您复制FileSystemUtils以实现“totalSpaceKB()”以委托等效的特定于操作系统的方法。 Windows的实现将是这样的(注意使用“查找”来修剪fsutil的输出以获得总大小):

long totalSpaceWindows(String path) throws IOException {
    path = FilenameUtils.normalize(path);
    if (path.length() > 2 && path.charAt(1) == ':') {
        path = path.substring(0, 2); // seems to make it work
    }

    // build and run the 'fsutil' command
    String[] cmdAttribs = new String[] {
            "cmd.exe",
            "/C",
            "fsutil volume diskfree " + path
                    + " | Find \"Total # of bytes\"" };

    // read in the output of the command to an ArrayList
    List lines = performCommand(cmdAttribs, Integer.MAX_VALUE);

    //because we used Find, we expect the first line to be "Total # of bytes",
    //you might want to add some checking to be sure
    if (lines.size() > 0) {
        String line = (String) lines.get(0);
        String bytes = line.split(":")[1].trim();
        return Long.parseLong(bytes);
    }
    // all lines are blank
    throw new IOException(
            "Command line 'fsutil volume diskfree' did not return 
                    + "any info  for path '" + path + "'");
}

Unix的实现与freeSpaceUnix()相同,但在方法结束时删除对tok.nextToken()的两次调用

    /** comment these two lines so the token received is the total size */
    tok.nextToken(); // Ignore 1K-blocks
    tok.nextToken(); // Ignore Used
    /** this will now be the total size */
    String freeSpace = tok.nextToken();
    return parseBytes(freeSpace, path);
}

其他平台的实现方式类似。

希望这有助于误解这个问题而道歉。


原始答案(获取免费字节,而不是总数)。

在Java 6之前,没有一种优雅的方法可以做到这一点,(参见bug)。我建议您使用库来为您执行特定于平台的处理,而不是自己编写。

Apache commons-io具有FileSystemUtils类型,提供静态方法freeSpaceKb()。它适用于Windows和一些Unix实现(参见下面的Javadoc引用)

来自Javadoc:

  

public static long freeSpaceKb(String path)                           抛出IOException

     

通过调用命令行返回驱动器或卷上的可用空间(以KB为单位)。    FileSystemUtils.freeSpaceKb( “C:”); // Windows    FileSystemUtils.freeSpaceKb( “/体积”); // * nix

     

通过命令行计算可用空间。它在Windows上使用'dir / -c',在AIX / HP-UX上使用'df -kP',在其他Unix上使用'df -k'。   为了工作,您必须运行Windows,或者在传递-k(或-kP)时具有支持GNU格式的Unix df的实现。如果您要依赖此代码,请通过运行一些简单的测试来检查它是否适用于您的操作系统,以将命令行与此类的输出进行比较。如果您的操作系统不受支持,请提出一个JIRA电话,详细说明df -k的确切结果以及尽可能多的其他细节,谢谢。

答案 1 :(得分:1)

注意:此解决方案仅建议用作最后一次尝试

我不知道这是否存在于任何API /库中。但是,作为最后一次尝试,我可能会创建一个Ant脚本或使用Ant任务实现来执行适合于该平台的OS命令,然后解析输出流。为何选择Ant? - 因为它提供:

  • 良好的平台识别(见os condition
  • 平台独立command execution
  • 能够以编程方式解析命令执行的输出 - 将输出写入属性,然后从Ant project对象访问它。

是的,这有点乱,但您可以使用Ant API执行所述目标,然后使用您自己的界面将其全部包装起来。这仍然不一定涵盖所有可能的系统 - 只有Ant可以识别的系统。

此外,它仍然是一项相当多的工作,您需要为所有目标平台制定正确的命令和解析策略。

再次 - 最后一次尝试 - 等待其他答案并继续搜索其他库和API产品。

答案 2 :(得分:0)

在SUN的

Here free 磁盘空间问题有很长的历史。 他们提到JConfig作为可能的解决方案。不幸的是,这个图书馆只能在2009年夏末(希望)到达,现在还不清楚它是否解决了原始问题,因为文档和来源不可用,但他们说:

  

它允许您处理文件,网络   浏览器,进程,文件类型和   很多其他系统级项目   比那更先进的方式   由标准Java类提供   库。例如,你可以使用   它可以启动Web浏览器或其他   外部应用程序而不是使用   Runtime.exec或仅限解决方案   在一个平台上工作。

所以,如果你有耐心和幸运......