Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File.getCanonicalPath() failure examples

Tags:

java

file-io

Does anyone have an experience or know when the method File.getCanonicalPath() will throw an IOException

I have tried to look up from the Internet and the best answer is in File API which says

"IOException - If an I/O error occurs, which is possible because the construction of the canonical pathname may require filesystem queries"

However, it is not clear to me because I still cannot think of a case which this might fail. Can anyone give me concrete examples which can happen on Linux, Windows and other OS (optional)?

I reason I want to know is because I want to handle this exception accordingly. Thus, it will be best if I know all the possible failures that can happen.

like image 571
gigadot Avatar asked Dec 20 '10 13:12

gigadot


3 Answers

Here is a Windows example:

Try calling getCanonicalFile on a file in your CD-drive, but without a CD loaded. For example:

new File("D:\\dummy.txt").getCanonicalFile();

you will get:

Exception in thread "main" java.io.IOException: The device is not ready
    at java.io.WinNTFileSystem.canonicalize0(Native Method)
    at java.io.Win32FileSystem.canonicalize(Win32FileSystem.java:396)
    at java.io.File.getCanonicalPath(File.java:559)
    at java.io.File.getCanonicalFile(File.java:583)
like image 148
dogbane Avatar answered Oct 19 '22 15:10

dogbane


The IO Exception also occurs if we try creating a File object with Windows device file keywords (see device files) used as file name.
As if you try renaming the file to those keywords, Windows will not let you to make it (no CON, PRN, COM1 etc. file names allowed), Java also won't be able to convert that file name to the correct path.

So, any of next next code will trow the IO Exception:

File file = new File("COM1").getContextPath();
File file = new File("COM1.txt").getContextPath();
File file = new File("C:/somefolder/COM1.txt").getContextPath();

However, next code should work:

File file = new File("COM1_.txt").getContextPath();  //underscore wins :)
like image 37
AndrewNR Avatar answered Oct 19 '22 15:10

AndrewNR


Here is generic example for all OS:

new File("\u0000").getCanonicalFile();

Before canonicalizing of the file, its validity is checked with java.io.File#isInvalid:

final boolean isInvalid() {
    if (status == null) {
        status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
                                                   : PathStatus.INVALID;
    }
    return status == PathStatus.INVALID;
}

And if the file is invalid - you'll get an IO exception:

public String getCanonicalPath() throws IOException {
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }
    return fs.canonicalize(fs.resolve(this));
}

Profit!

like image 5
ursa Avatar answered Oct 19 '22 16:10

ursa