Java IO FileNotFoundException after converting file name toURL() - java

Here is the Jython code (although this may not be a Jython-specific issue)...
file_name = "Manifest.ttl"
file_url = File(file_name).toURL()
f = File(file_url.toString())
java.io.FileNotFoundException: java.io.FileNotFoundException:
file:/home/james/projects/wordnet/wordnet30/rdf/Manifest.ttl (No such
file or directory)

Javadoc to the rescue:
Creates a new File instance by converting the given pathname string
into an abstract pathname. If the given string is the empty string,
then the result is the empty abstract pathname.
Parameters:
pathname - A pathname string
The File constructor takes an abstract path name as argument, not the toString representation of a URL.
Besides, toURL is deprecated. You might use toURI, and reconstruct the file with this URI.

toURL() adds the file:// prefix that a proper URL/URI requires. Clearly the File constructor doesn't check and remove this prefix, so it's looking for a file called "file://..." instead of where you want it to look "/home/james/...".

Related

Empty File constructor is neither file nor directory

What is the difference between the following two methods for creating a file?
new File(System.getProperty("user.dir"));
new File("");
Java identifies the first one as a directory, and the second one's neither a file nor a directory! Why is that the case?
Code:
public class MainClass {
public static void main(String[] args) throws Exception {
System.out.println("File Created with CurrentDir taken From System Props");
File f1 = new File(System.getProperty("user.dir"));
System.out.println("Absolute Path: " + f1.getAbsolutePath());
System.out.println("isDirectory: " + f1.isDirectory());
System.out.println("isFile: " + f1.isFile());
System.out.println();
System.out.println("File Created with Empty String Path");
File f2 = new File("");
System.out.println("Absolute Path: " + f2.getAbsolutePath());
System.out.println("isdirectory: " + f2.isDirectory());
System.out.println("isFile: " + f2.isFile());
}
}
Output:
File Created with CurrentDir taken From System Props
Absolute Path: D:\Java Workspace\my_Workspace\JavaTest
isDirectory: true
isFile: false
File Created with Empty String Path
Absolute Path: D:\Java Workspace\my_Workspace\JavaTest
isdirectory: false
isFile: false
Explanation
It may seem a little non-intuitive but actually that's just how the class is supposed to work according to its documentation. It's called empty abstract pathname in the documentation:
The empty abstract pathname has no prefix and an empty name sequence.
And from your constructor File#File(String):
Creates a new File instance by converting the given pathname string into an abstract pathname. If the given string is the empty string, then the result is the empty abstract pathname.
So the File class actually interprets the empty name as actual name. When you test File#isDirectory() or File#isFile() it thus checks if there exists a file or directory like
D:\Java Workspace\iTAW_Workspace\JavaTest\<empty>
Note the <empty> which I wrote to indicate that it actually searches for a file here with the empty name. Obviously such a file can not exist, thus the result will always be false. So again, it does not check
D:\Java Workspace\iTAW_Workspace\JavaTest\
but rather the empty file in this directory, which does not exist.
Unfortunately you don't see this when using the File#toAbsolutePath() method as there is no representation for an empty name.
NIO
Note that the class File and everything related to it is outdated. Nowadays file IO is done using NIO revolving around Files, Paths and Path. This API is much more cleaner and more intuitive. It will also work as intended on your current example:
Files.isDirectory(Paths.get("")); // true
Take a look at the documentation for more.
Creating a file with empty string results to creating a File instance which actually does not exist and its absolute pathname is "empty abstract pathname".
-> That's why the second one's neither a file nor a directory for you.
The reason behind that, a maybe little bit confusing output for you, is definition located in javadocs:
If this abstract pathname is the empty abstract pathname then the
pathname string of the current user directory, which is named by the
system property user.dir, is returned.
You can find more about this topic here
https://docs.oracle.com/javase/6/docs/api/java/io/File.html
You need to make the difference between the Java object File and a file actually present on your computer.
In the first case : new File(System.getProperty("user.dir")). You create a Java object File and give him a path : System.getProperty("user.dir"). Later when you call the function .getAbsolutePath() it returns you the path you gave. Then when you call .isDirectory() it tells you true because there is a directory corresponding to this Java object File.
In the second case, new File("") it creates a Java object File and you give it a path : "". Since the path given is not absolute, the system will resolve it as a relative from the user.dir path.
from documentation
A pathname, whether abstract or in string form, may be either absolute or relative. An absolute pathname is complete in that no other information is required in order to locate the file that it denotes. A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.
Later when you call the function .getAbsolutePath() it returns you the path you gave, so the path to user dir + empty string : D:\Java Workspace\iTAW_Workspace\JavaTest\<empty>. Then when you call .isDirectory() it tells you false because there is no directory corresponding to this path. (same reason for isFile())
new File("") creates new file with relative (empty) path. As this file doesn't exist both isDirectory() and isFile() return false (corresponds to javadoc).
From javadoc
boolean java.io.File.isDirectory()
...
Returns: true if and only if
the file denoted by this abstract pathname exists and is a directory;
false otherwise
The same is true for isFile(). and as long as your file doesn't exist both methods return false.

Check that a given path points to a file under a certain subfolder

I get, as input from the user, a path to a certain file.
The user is allowed to access this file, only if the file is inside a certain parent-folder "User/".
For example:
"User/1/2/3" is good.
"User/1/../2" is good.
"User/1/../../2" is not good (goes outside "User/" folder).
"Parent/../User/1/2/3" is good.
Is there a simple way to check this in Java?
How about:-
boolean allowed = new File("the/path").getCanonicalPath().contains("User/");
You can construct a File from the given pathname and loop over the File#getParent() chain:
public boolean check(final String pathname) throws IOException {
for(File target = new File(pathname).getCanonicalFile();
null != target;
target = target.getParentFile()) {
if("User".equals(target.getName())) {
return true;
}
}
return false;
}
Just remember to resolve the given pathname using File#getCanonicalFile().
You can use File#getCanonicalPath. Below you can find an excerpt of its Javadoc.
Returns the canonical pathname string of this abstract pathname. A
canonical pathname is both absolute and unique. The precise definition
of canonical form is system-dependent. This method first converts this
pathname to absolute form if necessary, as if by invoking the
getAbsolutePath() method, and then maps it to its unique form in a
system-dependent way. This typically involves removing redundant names
such as "." and ".." from the pathname, resolving symbolic links (on
UNIX platforms), and converting drive letters to a standard case (on
Microsoft Windows platforms).

How does file.getAbsolutePath work?

This is the code:
String filename = "sql.txt";
File file = new File(filename);
String path = file.getAbsolutePath();
System.out.println(path);
My text file resides in E drive but when I print out the path it is in C drive. Why does this happen?
You have provided a path which is neither absolute nor canonical.
String filename = "sql.txt";
Hence, the pathname is returned as simply the current user directory.
Have a look at the documentation for the getAbsolutePath() method in the File class:
If this abstract pathname is already absolute, then the pathname
string is simply returned as if by the getPath() method. If this
abstract pathname is the empty abstract pathname then the pathname
string of the current user directory, which is named by the system
property user.dir, is returned. Otherwise this pathname is resolved in
a system-dependent way. On UNIX systems, a relative pathname is made
absolute by resolving it against the current user directory. On
Microsoft Windows systems, a relative pathname is made absolute by
resolving it against the current directory of the drive named by the
pathname, if any; if not, it is resolved against the current user
directory.
Follow those steps
Go to run configuration
Click argument tab
Change the working directory to ${workspace_loc:myproject}
Reference
Java workspace and file path

Reading File Direction/Path Java

I want to read the path of a file. All I've found is about the class file, how to read the file or how to save the file in this direction.
But what I want is a method that shows me the path like this:
C:/Users/Administrator/Documents/NetBeansProjects/HashmapDemo/HeaderTemplate
So that i can save this direction in a XML file.
I hope it is understandable what I mean, I tend to write things nobody can understand.
I've tried:
public static String getCleanPath() {
ClassLoader classLoader = XmlLoader.class.getClassLoader();
File classpathRoot = new File(classLoader.getResource("").getPath());
return classpathRoot.getPath();
}
So far but like I said, it doesn't give me the information I need.
Maybe the getAbsoulePath() method is what you are looking for?
public String getAbsolutePath()
Returns the absolute pathname string of this abstract pathname.
If this abstract pathname is already absolute, then the pathname
string is simply returned as if by the getPath() method. If this
abstract pathname is the empty abstract pathname then the pathname
string of the current user directory, which is named by the system
property user.dir, is returned. Otherwise this pathname is resolved in
a system-dependent way. On UNIX systems, a relative pathname is made
absolute by resolving it against the current user directory. On
Microsoft Windows systems, a relative pathname is made absolute by
resolving it against the current directory of the drive named by the
pathname, if any; if not, it is resolved against the current user
directory.
Returns: The absolute pathname string denoting the same file or
directory as this abstract pathname

What does abstract path means in java.io?

In java doc about
File#getPath()
writes:
Converts this abstract pathname into a pathname string.
I try to write1
File file3 = new File("D:\\work");
System.out.println(file3.getPath());
In cmd I see D:\\work
I try to write2:
File file4= new File("file4");
System.out.println(file4.getPath());
In cmd I see:
file4
Thus I have a question:
What the difference between
abstract pathname
and
pathname string
?
An abstract pathname is a java.io.File object and a pathname string is a java.lang.String object. Both reference the same file on the disk.
How do I know?
The first sentence of the Javadoc of java.io.File explains:
An abstract representation of file and directory pathnames.
It goes on to explain why:
User interfaces and operating systems use system-dependent
pathname strings to name files and directories. This class
presents an abstract, system-independent view of hierarchical
pathnames.
The abstract pathname is just the string form of the file/location held in the File object.
If you check the javadoc of File#toString():
Returns the pathname string of this abstract pathname. This is just the string returned by the getPath() method.
See javadoc: abstract pathname = File
An optional system-dependent prefix string, such as a disk-drive specifier, "/" for the UNIX root directory, or "\\" for a Microsoft Windows UNC pathname, and
A sequence of zero or more string names. [refering to directories and file
These are independent of operating system peculiarities of notation.
The string form gives you what you need to write on your current operating system to refer to that file.

Categories

Resources