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

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

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

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

有什么想法吗? 谢谢。

更新:

我为误读这个问题而道歉,我建议复制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”列感兴趣(下面的Wikipedia示例)。 你显然需要将结果乘以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()”以委托等效的特定于OS的方法。 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(“/ volume”); // * nix

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

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

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

  • 良好的平台识别(参见os条件 )
  • 平台独立的命令执行
  • 能够以编程方式解析命令执行的输出 – 将输出写入属性,然后从Ant 项目对象访问它。

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

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

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

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

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

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