this only works on windows. its a hack and yes i agree
with bla on this one also. bit of an on going joke.
public static final long getFreeSpace(File file) throws IllegalArgumentException, IllegalStateException, IOException {
if (file == null) throw new IllegalArgumentException("file == null");
if (System.getProperty("os.name").startsWith("Windows"))
return getFreeSpaceInWindows(file);
//else if (System.getProperty("os.name").startsWith("..."))
// return ...
else
throw new IllegalStateException("getFreeSpace(File) currently does not support this operating system: " + System.getProperty("os.name"));
}
private static final long getFreeSpaceInWindows(File file) throws IllegalStateException, IOException {
PrintWriter writer = null;
BufferedReader reader = null;
try {
// create a temp .bat file to run the dir command:
File script = File.createTempFile("script", ".bat");
script.deleteOnExit();
writer = new PrintWriter( new FileWriter(script, false), true );
writer.println("dir \"" + file.getCanonicalPath() + "\"");
writer.close(); // MUST close it at this point, else the Process below will fail to run
// get output from running the .bat file:
Process p = Runtime.getRuntime().exec( script.getAbsolutePath() );
reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
String line = null;
while (true) {
line = reader.readLine();
if (line == null) throw new IllegalStateException("Failed to encounter the expected output (a line ending with the text \"free\") while parsing the output of the dir command");
else if (line.endsWith("free")) break;
}
// Here are some real examples seen of what line can look like:
// 12 dir(s) 631,889,920 bytes free
// 10 dir(s) 24,167.73 MB free
// 788,021,248 bytes free
// (This last case happens if there are no contents inside volume)
// The parsing code below MUST handle all these cases
// parse the number (of bytes free) from line:
String[] tokens = line.split("\\s+", -1); // in ALL cases, should have tokens[tokens.length - 3] = "788,021,248", tokens[tokens.length - 2] = "bytes" or "KB" or "MB" or "GB", tokens[tokens.length - 1] = "free"
String numberText = tokens[tokens.length - 3].replaceAll(",", ""); // replaceAll eliminates the commas but NOT any decimal point
String unit = tokens[tokens.length - 2];
if (unit.equals("bytes"))
return Long.parseLong(numberText);
else {
System.err.println("--------------------------------------------------");
System.err.println("WARNING: POSSIBLE LOSS OF PRECISION in determining the free space");
System.err.println("The operating system reported the free space as " + numberText + " " + unit);
System.err.println("This output may have been rounded, however, which means that the exact number of bytes is impossible to determine");
System.err.println("--------------------------------------------------");
double number = Double.parseDouble(numberText);
if (unit.equals("KB")) return (long) (number * 1024); // see http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&threadm=QNJ6c.54315%24H44.994342%40bgtnsc04-news.ops.worldnet.att.net&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.os.msdos.programmer
else if (unit.equals("MB")) return (long) (number * 1024 * 1024);
else if (unit.equals("GB")) return (long) (number * 1024 * 1024 * 1024);
else throw new IllegalStateException("Program encountered unit = " + unit + " which it is unable to handle");
}
}
finally {
if (writer != null) writer.close();
if (reader != null) reader.close();
}
}