Getting file system details in Java

Due to a number of differences between various platforms it is very difficult to present system specific information in a consistent manner. When getting closer to system specific details, like file system information, a Java programmer has to become aware of the operating system hosting his program in order to make sense of the information returned by some of the Java APIs. Getting detailed information about a file system in Java is pretty difficult without using system specific code like JNI or at least accessing various specific operating system resources like configuration files.
Java offers two ways of getting some file system information through java.io.File and javax.swing.filechooser.FileSystemView classes. On some systems like Linux the information obtained from these two APIs is identical, while on others like Windows is quite different.

The sample code shows how to get file system information and the output differences on Windows and Solaris:

package com.littletutorials.fs;

import java.io.*;
import javax.swing.filechooser.*;

public class DriveTypeInfo
{
    public static void main(String[] args)
    {
        System.out.println("File system roots returned by FileSystemView.getFileSystemView():");
        FileSystemView fsv = FileSystemView.getFileSystemView();
        File[] roots = fsv.getRoots();
        for (int i = 0; i < roots.length; i++)
        {
            System.out.println("Root: " + roots[i]);
        }

        System.out.println("Home directory: " + fsv.getHomeDirectory());

        System.out.println("File system roots returned by File.listRoots():");
        File[] f = File.listRoots();
        for (int i = 0; i < f.length; i++)
        {
            System.out.println("Drive: " + f[i]);
            System.out.println("Display name: " + fsv.getSystemDisplayName(f[i]));
            System.out.println("Is drive: " + fsv.isDrive(f[i]));
            System.out.println("Is floppy: " + fsv.isFloppyDrive(f[i]));
            System.out.println("Readable: " + f[i].canRead());
            System.out.println("Writable: " + f[i].canWrite());
            System.out.println("Total space: " + f[i].getTotalSpace());
            System.out.println("Usable space: " + f[i].getUsableSpace());
        }
    }
}

Running this code on Windows will produce this kind of output:

File system roots returned by FileSystemView.getFileSystemView():
    Root: C:\Documents and Settings\dpietrar\Desktop

Home directory: C:\Documents and Settings\dpietrar\Desktop

File system roots returned by File.listRoots():
Drive: A:\
    Display name: 
    Is drive: true
    Is floppy: true
    Readable: false
    Writable: false
    Total space: 0
    Usable space: 0
Drive: C:\
    Display name: Data (C:)
    Is drive: true
    Is floppy: false
    Readable: true
    Writable: true
    Total space: 79990812672
    Usable space: 39353810944
Drive: D:\
    Display name: Backup (D:)
    Is drive: true
    Is floppy: false
    Readable: true
    Writable: false
    Total space: 717684736
    Usable space: 0
Drive: H:\
    Display name: daniel on 'File Server (Filesvr)' (H:)
    Is drive: true
    Is floppy: false
    Readable: true
    Writable: true
    Total space: 1310720000
    Usable space: 801497088


Running this same code on Solaris displays:

File system roots returned by FileSystemView.getFileSystemView():
    Root: /

Home directory: /home/daniel

File system roots returned by File.listRoots():
Drive: /
    Display name: /
    Is drive: false
    Is floppy: false
    Readable: true
    Writable: false
    Total space: 1310720000
    Usable space: 801497088


As you can see making sense of the information in a useful way requires to know in advance the kind of operating system your program is running on.
Unfortunately here is where the abstraction breaks and the differences leak into the code. For example based on the information above it is almost impossible to detect a CD-ROM drive with 100% certainty without resorting to JNI code or some similar solution.