gigadot
gigadot

Reputation: 8969

File.getCanonicalPath() failure examples

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.

Upvotes: 17

Views: 15455

Answers (5)

ursa
ursa

Reputation: 4601

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!

Upvotes: 5

Anver Sadhat
Anver Sadhat

Reputation: 3240

One more scenario, When you try to use Operating System restricted/invalid characters as your file name.

For Windows \ / : * ? " < > | these are the invalid characters. Try to rename a file with : you will get a balloon/tip message about the invalid characters.

Try the Following Java Code.

File file = new File("c:/outputlog-2013-09-20-22:15"); 
//A common scenario when you try to append java.util.Date to create a file like
//File newFile = new File(filename + "_" + new Date());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());

If the File name contains
* ? you will get java.io.IOException: Invalid argument
| : you will get java.io.IOException: The filename, directory name, or volume label syntax is incorrect


when you use the getCanonicalPath() method.

If we use any of " < > char in the file name, then getCanonicalPath() method is not failing but when you try to create the file you will be getting the Invalid argument Exception.

Refer jdk7 api

The precise definition of canonical form is system-dependent. Here I have used windows 7.

Upvotes: 3

AndrewNR
AndrewNR

Reputation: 61

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 :)

Upvotes: 6

LaGrandMere
LaGrandMere

Reputation: 10359

Seen here in the Sun Bug Database.

For JRE 1.4.2_06, File.getCanonicalPath() wasn't working on Windows for a removable drive when there is no media present in the drive.

It was corrected in Java 1.5, but you can see there can be OS-based problems with this method.

I don't know of any problem in the current time, but it can happen, that's exactly what the Javadoc says. Usually it's quickly fixed in the newest Java version.

Upvotes: 3

dogbane
dogbane

Reputation: 274720

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)

Upvotes: 18

Related Questions