一个Java程序如何在Linux上列出所有分区并获取它们的可用空间?

3
我希望能够使用Java程序查询Linux系统中每个分区的名称以及其总空间、已用空间和可用空间。在Windows系统中,我得到了正确的值,但在Linux系统中,我只能获得一个驱动器的信息。目前为止,以下是我尝试过的方法。
public class DiskSpace {

public static void main(String[] args) {
    FileSystemView fsv = FileSystemView.getFileSystemView();
    File[] drives = File.listRoots();
    if (drives != null && drives.length > 0) {
        for (File aDrive : drives) {
            System.out.println("Drive Letter: " + aDrive);
            System.out.println("\tType: " + fsv.getSystemTypeDescription(aDrive));
            System.out.println("\tTotal space: " + aDrive.getTotalSpace());
            System.out.println("\tFree space: " + aDrive.getFreeSpace());
            System.out.println();
        }
    }
}

3
Linux 没有驱动器,而是拥有已挂载的文件系统。因此,在 Linux 上你的问题没有任何意义。在终端中运行命令 dfmount 可以了解已挂载的文件系统。请注意不要改变原文意思。 - Basile Starynkevitch
当你说“只有一个驱动器信息”时,你的意思是什么? - Behe
我的意思是它显示根文件的信息。从编程角度来看,我如何获取所有文件的信息? - Sudarshan kumar
4个回答

6

Linux系统中没有驱动器字母。如果您想知道有哪些分区以及它们被挂载到了哪里,请阅读/proc/mounts。当您有一个挂载点(在/proc/mounts的第二列)时,使用new File(mountpoint).getTotalSpace()来获取总可用空间。


@Basile:如果他想编写一个“通用”的Java程序,那么读取/proc/mounts比从Java中调用dfmount要容易得多 - 似乎他的程序旨在“替换”df。当然,如果他想在任何其他类型的类Unix系统上使用自己的程序,他将遇到/proc/mounts的问题。 - Guntram Blohm
我同意你的观点。我建议在终端中运行 dfmount 是为了让 OP 理解一些东西。然后,如果他真的需要以编程方式获取信息,他可以使用 /proc/mounts,但他可能需要避免像 /procsystemdbinfmt_miscudevdevptsfusectlpstore 伪文件系统这样的特殊情况。所以这可能比你提出的更困难。 - Basile Starynkevitch
同意。有时候,“明白点”这样的委婉说法是最好的回答 ;) - Guntram Blohm

4
Linux、Unix和类Unix系统只有一个文件系统,其中有一个根,可以在该根下挂载多个挂载点,这些挂载点包含Unix文件系统的部分或全部分区,非Unix文件系统也可使用适当的软件进行挂载以处理必要的转换,但仍保持了统一的单根文件系统模型。如果您使用的FileSystemView类来自javax.swing.filechooser包,请不要期望太多:FileSystemView是JFileChooser访问文件系统的入口。由于JDK 1.1文件API不允许访问诸如根分区、文件类型信息或隐藏文件位之类的信息,因此设计了此类以尽可能直观地获取特定于操作系统的文件系统信息。Java许可证持有人可能希望提供FileSystemView的不同实现,以更好地处理特定操作系统。第二段是关键。
Java的虚拟机实现旨在抽象出你在这种情况下需要的特定平台相关的东西。为了成功,你需要编写或查找每个支持平台的本地系统API的本地调用包装类。像FileSystemView类这样的“高级”抽象可能无法完全或可靠地提供所需的信息。

2
这是一个显示已挂载外部媒体名称的代码片段。
String OS = System.getProperty("os.name");
if(OS.equals("Linux"))
{
    String s = "";
    Runtime rt = Runtime.getRuntime();
    int n=0;
    Process ps = rt.exec("ls /run/media/Rancho");// Write your UserName, mine is Rancho

    InputStream in = ps.getInputStream();
    while((n = in.read())!=-1)
    {
        char ch = (char) n;
        s+ = ch;
    }
    System.out.println(s);  
}

0

我知道我来晚了,但我写了一个只做它该做的事情的类。它所做的是读取/proc/mounts文件,将其解析为块设备(如/dev/sda)、挂载点、文件系统类型及其挂载选项。如果您不需要我编写的其他内容,可以将其排除在外,但对于我正在工作的项目,我想包括它,例如当前用户是否可以写入或从当前挂载点读取。

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class UnixPartition {

    private final String block, mount, fsType, mntOptions;
    private final long totalSpace, freeSpace, usableSpace;
    private final File root;

    protected UnixPartition(String block, String mount, String fsType, String mountOptions, long totalSpace, long freeSpace, long usableSpace, File root) {
        this.block = block;
        this.mount = mount;
        this.fsType = fsType;
        this.mntOptions = mountOptions;
        this.totalSpace = totalSpace;
        this.freeSpace = freeSpace;
        this.usableSpace = usableSpace;
        this.root = root;
    }

    public String getBlock() {
        return block;
    }

    public String getMount() {
        return mount;
    }

    public String getFilesystemType() {
        return fsType;
    }

    public long getTotalSpace() {
        return totalSpace;
    }

    public long getFreeSpace() {
        return freeSpace;
    }

    public long getUsableSpace() {
        return usableSpace;
    }

    public String getMountOptions() {
        return mntOptions;
    }

    public boolean canCurrentUserWrite() {
        return root.canWrite();
    }

    public boolean canCurrentUserRead() {
        return root.canRead();
    }

    private String getLineSeparator(String contents) {
        char[] chars = contents.toCharArray();

        long r = 0;
        long n = 0;

        for (char c : chars) {
            if (c == '\r')
                r++;

            if (c == '\n')
                n++;
        }

        if (r == n)
            return "\r\n";
        else if (r >= 1 && n == 0)
            return "\r";
        else if (n >= 1 && r == 0)
            return "\n";
        else
            return "";
    }

    public static List<UnixPartition> getPartitions(boolean filterSpecials) throws IOException {
        String contents = new String(FileUtil.read("/proc/mounts"));
        String[] lines = contents.split(getLineSeparator(contents));

        List<UnixPartition> partitions = new ArrayList<>();

        for (String line : lines) {
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            String blk = tokenizer.nextToken(),
                    mnt = tokenizer.nextToken(),
                    type = tokenizer.nextToken(),
                    opt = tokenizer.nextToken();

            if (filterSpecials) {
                if ((blk.contains("proc") || mnt.contains("proc") || type.contains("proc")) ||
                        (blk.contains("systemd") || mnt.contains("systemd") || type.contains("systemd")) ||
                        (blk.contains("binmft_misc") || mnt.contains("binmft_misc") || type.contains("binmft_misc")) ||
                        (blk.contains("udev") || mnt.contains("udev") || type.contains("udev")) ||
                        (blk.contains("devpts") || mnt.contains("devpts") || type.contains("devpts")) ||
                        (blk.contains("fuse") || mnt.contains("fuse") || type.contains("fuse")) ||
                        (blk.contains("pstore") || mnt.contains("pstore") || type.contains("pstore")) ||
                        type.contains("tmp"))
                    continue;

                if (blk.contains("none"))
                    continue;
            }

            File root = new File(mnt);

            partitions.add(new UnixPartition(blk, mnt, type, opt,
                    root.getTotalSpace(), root.getFreeSpace(), root.getUsableSpace(), root));
        }

        return partitions;
    }

}

编辑:你可能需要自己过滤掉特殊的挂载类型,因为我只是从另一个答案中使用了它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接