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'.
Related
I'm trying to use a file in my code but I don't want to have specify the absolute file path, only the file name, for example "fileName.txt".
I want to do this so I have the ability to use this code on different laptops where the file may be stored in different folders.
The code below is what I'm using at the moment but I receive a NoSuchFileException when I ran it.
FileSystem fs FileSystems.getDefault();
Path fileIn = Paths.get("fileName.txt");
Any ideas how to overcome this problem so I can find the file without knowing its absolute path?
Ideas on how to find the file without knowing its absolute path:
Instruct the user of the app to place the file in the working directory.
Instruct the user of the app to give the path to the file as a program argument, then change the program to use the argument.
Have the program read a configuration file, found using options 1 or 2, then instruct the user of the app to give the path to the file in the configuration file.
Prompt the user for the file name.
(Not recommended) Scan the entire file system for the file, making sure there is only one file with the given name. Optional: If more than one file is found, prompt the user for which file to use.
if you don't ask the user for the complete path, and you don't have a specific folder that it must be in, then your only choice is to search for it.
Start with a rootmost path. Learn to use the File class. Then search all the children. This implementation only returned the first file found with that name.
public File findFile(File folder, String fileName) {
File fullPath = new File(folder,fileName);
if (fullPath.exists()) {
return fullPath;
}
for (File child : folder.listFiles()) {
if (child.isDirectory()) {
File possible = findFile(child,fileName);
if (possible!=null) {
return possible;
}
}
}
return null;
}
Then start this by calling either the root of the file system, or the configured rootmost path that you want to search
File userFile = findFile( new File("/"), fileName );
the best option, however, is to make the user input the entire path. There are nice file system browsing tools for most environments that will do this for the user.
I'm creating a command line application that needs to output some files (more than one) into either a ZIP file or a plain folder depending on the paramters given.
My approach is to encapsulate the target (plain folder/ZIP file) with a FileSystem.
My problem is that I cannot sucessfully create a FileSystem object for a directory other than the current working directory denoting an absolute path on my hard disk:
public class FileSystemWriteTest {
public static void main(String[] args) throws IOException {
Path absolutePath = Paths.get("target", "testpath").toAbsolutePath();
System.out.println(String.format("user.dir before change:\n %s", System.getProperty("user.dir")));
System.setProperty("user.dir", absolutePath.toString());
System.out.println(String.format("changed user.dir:\n %s", System.getProperty("user.dir")));
FileSystem defaultSystem = FileSystems.getDefault();
Path testFilePath = defaultSystem.getPath("test.file");
System.out.println(String.format("expected to be in changed user.dir:\n %s", testFilePath.toAbsolutePath()));
URI uri = absolutePath.toUri();
System.out.println(String.format("URI: %s", uri));
FileSystem localFileSystem =
FileSystems.newFileSystem(uri, Collections.emptyMap());
Path file = localFileSystem.getPath("test.txt");
System.out.println(file.toAbsolutePath());
}
}
The output is:
user.dir before change:
D:\data\scm-workspace\anderes\Test
changed user.dir:
D:\data\scm-workspace\anderes\Test\target\testpath
expected to be in changed user.dir:
D:\data\scm-workspace\anderes\Test\test.file
URI: file:///D:/data/scm-workspace/anderes/Test/target/testpath/
Exception in thread "main" java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.WindowsFileSystemProvider.checkUri(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.newFileSystem(Unknown Source)
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
If I change to FileSystems.newFileSystem(Path, Classloader) the Exception changes to:
Exception in thread "main" java.nio.file.ProviderNotFoundException: Provider not found
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
Looks like this only works with regular files, not with directories.
So how can I create a FileSystem object for a directory other than pwd?
There is no built facility for creating a FileSystem with chroot like semantics. The default file system only supports file:/// as URI and doesn’t allow more than one instantiation.
In this regard, FileSystems.getDefault().getPath("test.file") creates a relative path, just like Paths.get("test.file"). The difference between relative paths created for the default file system and other file systems lies in the resolve behavior when no other base path has been specified (e.g. when calling toAbsolutePath() or just trying to open them). But being resolved against the current working directory does not make them a root path.
The best solution for implementing file system agnostic operations, is to let the code receive base Path objects, to resolve relative paths against.
E.g. a simple tree copy routine may look like:
static void copyTree(Path sourceBase, Path targetBase) throws IOException {
try {
Files.walk(sourceBase).forEach(path -> {
if(Files.isRegularFile(path)) try {
Path target = targetBase.resolve(sourceBase.relativize(path).toString());
if(!Files.isDirectory(target.getParent()))
Files.createDirectories(target.getParent());
Files.copy(path, target, StandardCopyOption.COPY_ATTRIBUTES);
} catch(IOException ex) {
throw new UncheckedIOException(ex);
}
});
} catch(UncheckedIOException ex) {
throw ex.getCause();
}
}
For this method, it doesn’t matter whether you’re copying from a harddrive directory to another harddrive directory or to a zip filesystem, or from a zip filesystem to the harddrive, or from a zip file to another zip file, etc.
The most interesting part is the invocation of sourceBase.relativize(path), to get the relative path from the source base path to the sub-path of the actual file. Since relative Path instances still are tied to a particular filesystem, the code invokes toString(), before passing it to targetBase.resolve(…), to ensure that it will work across different filesystems. Note that path.resolve(string) is equivalent to path.resolve(path.getFileSystem().getPath(string)). It would be legitimate, if the method first checks whether both Path instances belong to the same filesystem, to skip the String detour in that case.
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
I'm trying to launch a text file from a .jar file using Desktop.getDesktop().open(file)
String fileName = "file.txt";
URL url = getClass().getResource(fileName);
File fileToRead = new File(url.toURI());
Desktop.getDesktop().open(fileToRead);
I omitted the try-catch blocks for simplicity.
It is able to open my file when run from eclipse. But once I export to a .jar file, I get a NullPointerException in File fileToRead = new File(url.toURI());
When you package a class in a .jar file, it usually makes it nested one level deeper.
Therefore, you can try changing the first line to:
String filename = "../file.txt";
Looking at the JavaDoc of Class.getResource(String):
an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/', then the absolute name of the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.'.
Parameters:
name - name of the desired resource
Returns:
A URL object or null if no resource with this name is found
Your resource was not found, hence NullPointerException. Specify the path within the JAR as described by the JavaDoc (absolute path starting with '/' or relative to the class of this, the object where you are calling getClass().getResource(fileName)) and you should get it.
I am trying to understand "How to get to file by passing relative path of a file or folder?" . Here is the example:
CODE:
public class somex {
public static void main {
String fileName = System.getProperty("user.dir"); <---This gives me path for the current working directory.
File file = new File(fileName + "../../xml_tutorial/sample.xlsx" );
System.out.println(file.getCanonicalPath()); <---This gives me path for the file that is residing in folder called "xml_tutorial".
}
}
>>>>
Here, I know the file location so i was able to pass correct relative path. And, managed to print the file path. I have deleted the "sample.xlsx" and executed the above code; With no failing it gives me the path name and it is same path as when the file exists (i.e. before deleting). How it is possible ? I am expecting EXCEPTION here. why it is not throwing exception ?
Two, I want to use regular expression for the file name, such as: "../../xml_tutorial/samp.*". But this doesn't do the job and it gives me IOException. Why it is not able to identify the file sample.xlsx ? (NOTE: this is when the file exist and one hundred precent sure there is only one file with the name "sample.xlsx")
I have deleted the "sample.xlsx" and executed the above code; With no failing it gives me the path name and it is same path as when the file exists (i.e. before deleting). How it is possible ? I am expecting EXCEPTION here. why it is not throwing exception ?
File doesn't care whether the file actually exists. It just resolves the path. There's no need for the file to exist in order to take the path
/home/tjc/a/b/c/../../file.txt
...and turn it into the canonical form
/home/tjc/a/file.txt
If you want to know whether the file on that path actually exists, you can use the exists() method.
On your second, unrelated question:
Two, I want to use regular expression for the file name, such as: "../../xml_tutorial/samp.*". But this doesn't do the job and it gives me IOException. Why it is not able to identify the file sample.xlsx ?
There's nothing in the File documentation saying that it supports wildcards. If you want to do searches, you'll want to use list(FilenameFilter) or listFiles(FilenameFilter) and a FilenameFilter implementation, or listFiles(FileFilter) and a FileFilter implementation.