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
Related
I created the method where I get an absolute path but when I debug I get an incorrect path to the file which should be uploaded.
So, the method where I get absolute path:
public String getFilePathByFormat(String filePath) {
File file = new File(filePath);
return file.getAbsolutePath();
}
Then I use this method in the general low-level method for uploading:
public void uploadFile(WebElement webElement, String filePath){
try {
webDriver.manage().timeouts().implicitlyWait(40, SECONDS);
webElement.sendKeys(getFilePathByFormat(filePath));
}catch (Exception e){
printErrorAndStopTest();
}
}
And when I debug and evaluate incorrect path gets:
E:\acceptance-tests\src\test\resources, BUT after disk name, one more folder should be - where the project located.
What's wrong and why getAbsolutePath doesn't build the correct path?
Thanks
There are two types of file path in file system.
1) An absolute path always starts from root element and contains complete directory list required to locate the file. For example, '/Users/username/filename.txt' on Unix systems or 'C:\Users\username\filename.txt' on Windows systems.
A relative path does not have any directory listing and needs to be combined with another path in order to access a file. For example, username/filename.txt is a relative path; Note that it does not have any forward or backward slashes at the beginning.
getAbsolutePath() returns the absolute path of a file and works like below.
File object is created with absolute pathname - This method simply returns the pathname provided to create the file. And in case of Windows System, drive name is appended at beginning by default if it is not present in absolute path name given.
File object is created using relative path - Here relative path name is made absolute by resolving it against the current user directory.
In this case, absolute path '/acceptance-tests/src/test/resources/test4.pdf' is passed; As mentioned for windows system, drive details are prefixed with given path and returned as absolute path.
To make it work, you can pass the relative path of file 'src/test/resources/test4.pdf' or just pass the file name 'test4.pdf'.
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.
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
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.
I set java property user.dir to /home/alex/projects/poltava/rpgu/workingdir. Also I have file q.txt inside above folder.
Below is the code snippets and their return values (after =):
System.getProperty("user.dir") = /home/alex/projects/poltava/rpgu/workingdir
new File(".").getAbsolutePath() = /home/alex/projects/poltava/rpgu/workingdir/.
new File(".").exists() = true
new File("q.txt").getAbsolutePath() = /home/alex/projects/poltava/rpgu/workingdir/q.txt
new File("q.txt").exists() = false
new File(new File("q.txt").getAbsolutePath()).exists() = true
new FileInputStream("q.txt") = threw FileNotFoundException
So that as you can see file is realy exists in file system. When I try to get it with absolute path, everything is well. When I try to get it with relative path, it fails.
What do I wrong with relative path?
EDITED:
Small application that demonstrates the problem:
import java.io.File;
public class Test {
public static void main(String[] args) {
System.setProperty("user.dir", "/home/alex/projects/poltava/rpgu/workingdir");
System.out.println(System.getProperty("user.dir"));
System.out.println(new File("q.txt").exists());
System.out.println(new File("q.txt").isFile());
System.out.println(new File("q.txt").canRead());
System.out.println(new File("q.txt").getAbsolutePath());
System.out.println(new File(new File("q.txt").getAbsolutePath()).exists());
System.out.println(new File(new File("q.txt").getAbsolutePath()).isFile());
System.out.println(new File(new File("q.txt").getAbsolutePath()).canRead());
try {
new FileInputStream("q.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Output:
/home/alex/projects/poltava/rpgu/workingdir
false
false
false
/home/alex/projects/poltava/rpgu/workingdir/q.txt
true
true
true
java.io.FileNotFoundException: q.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:101)
at Test.main(Test.java:24)
EDITED 2:
I also tried another simple example:
File f = new File("q1.txt");
System.out.println(f.createNewFile());
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
An output:
true
q1.txt
/home/alex/projects/poltava/rpgu/workingdir/q1.txt
In result file is created in directory from which I launch the application. Not in user.dir directory. And getAbsolutePath() returns incorrect file path.
I think it would serve you better to read the javadoc for File.
A little bit of explanation to help you get started:
For the constructor that you're using:
public File(String pathname)
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 essentially what you get is a File instance, with the abstract pathname "q.txt".
What happens when you do a getAbsolutePath() on this. Again from the javadoc:
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.
Do you see what is happening? Especially, with respect to user.dir?
More hints:
Now create another variable, e.g.
File newFile = new File(System.getProperty("user.dir"), "q.txt").
Try the same operations on newFile. Try using getParent() on your previous one as well as on this one. You'll see the difference.
I hope this helps clarify a few points for you :)
It is because File(String str) will call normalize, but getAbsolutePath will also call resolve, there is where the user.dir is being used. Look at the following example.
System.setProperty("user.dir", "/home/alex/projects/poltava/rpgu/workingdir");
File fString = new File("Test.txt");
File fAbsolutePath = new File(fString.getAbsolutePath());
System.out.println(System.getProperty("user.dir"));
System.out.println(fString.getPath());
System.out.println(fAbsolutePath.getPath());
Here is the output:
/home/alex/projects/poltava/rpgu/workingdir
Test.txt
\home\alex\projects\poltava\rpgu\workingdir\Test.txt
You can see the src code here:
new File(String str)
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.%3Cinit%3E%28java.io.File%2Cjava.lang.String%29
getAbsolutePath:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.getAbsolutePath%28%29