Runtime.exec() fails with space in directory (Java) - java

I am trying to execute a process in the same directory as my Jar file by getting the location of the file with
private static File jarLocation = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile();
then calling
Runtime.getRuntime().exec("command", null, jarLocation);
This usually works just fine but when the path has a space in it I get "The directory name is invalid". I have attempted to add some debug code which prints the path of the directory which has replaced spaces with "%20" (I assume because the ASCII hex of space is 20). is there a way to be able to use a directory with spaces in its path?

That getPath() call, which is URL.getPath(), does not return a filesystem path. It returns the path portion of a URL. In the case of a file: URL, it will be a URL-encoded local filesystem path. If that original URL is in fact a file: URL, you need to use the URI and URL classes, or custom string processing, to convert that to a local filesystem path that the Runtime.exec() can work with.
This might work directly in your case.
File jarLocation = Paths.get(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toFile();
You can also see the discussion at Converting Java file:// URL to File(...) path, platform independent, including UNC paths.

Related

String changes its value causing a java.io.FileNotFoundException

I am loading a document from a file, this file (which is in a URL) for some reason changes its name causing the java.io.FileNotFoundException.
Although I use a user input I have tried putting the name of the file directly, but it shows the same error.
File input = new File("/example/");
I expect the file name to be /example/, but the debugging shows it to be \example
You are obviously running your code in a Windows OS, which uses '\' as its file path separator character.
File automatically converts file separators ('/' and '\'), no matter what is specified in the String path, to the local file system's separator, thereby using the normalized local form, which is what you are seeing.
Your path is a absolute path, so the example file should be in the root directory. If you are expecting the file to be relative to where you are running your app from, remove the leading / to make it a relative path.

maven read file input from user

I am pretty new to Maven, and having some trouble reading files. Specifically, my program takes the absolute path of a file as input from the user, and then parses it. Unfortunately I am unclear on how to get my application to read a file as input from an arbitrary location.
Before I started using maven on the project, I used this code successfully:
String absolutePath = "/Users/akhalsa/path/to/file.txt";
inputStream = new BufferedReader(new FileReader(absolutePath));
However, since migrating to maven, this seems to have stopped working. From what I have read in maven I should use
InputStream in = getClass().getResourceAsStream(filePath);
Where filePath seems to be the relative path of the file in question. Does getResourceAsStream require that the file being read be inside the jar? Can this file be an external file's absolute path? When I use an absolute path here it says "Resource not found".
This must be a common problem in terms of letting users input a file from the file system for a maven application to process. What is the best way to this?
Thanks in advance.
getResourceAsStream() finds the resource on a path known to the jvm, so you can't load arbitrary files.
Maven does no magic trickery so if you are using actual absolute paths, the code should keep on working.
The "Users" part of the path reminds me of windows, but the path is not a valid windows path so are you sure you are passing along a valid absolute path?

get a file path

Is there a way to get the full path for a file exists on the computer ?
For example , I want to get the full path for a file in a folder on desktop
I tried using :
File f = new File("help.chm");
String f2=f.getAbsolutePath();
f3=f3.replaceAll("\\\\","/" );
System.out.println("Path:"+f3);
but it gave me the path of the project like this:
C:/Users/toshiba/Documents/NetBeansProjects/test/help.chm
although the file is not located there .
If you create a file using new File("filename") which is the relative path, you cannot get the absolute path of the file using file.getAbsolutePath(), because the relative path is build according to the default user home directory or the JVM path.
Take a look at Java Doc: -
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.
So, to get the absolute path for this case, you would actually have to write the path yourself. Get the absolute path till the directory where you saved the file, and append the file name to it.
Since the other answers do not cover your question, here is my comment:
To get a file's path, you first need to tell your java program where it is or how to find it.
For your specific example you can get the desktop path using: System.getProperty("user.home") + "/Desktop"; then you can search through folders on your desktop for a matching file name.
Read here to learn how to search for files: docs.oracle.com/javase/tutorial/essential/io/find.html
A File is a representation of a file path, not necessarily an existent file on disk - ie the file doesn't have to exist on disk for a File object to be not null.
That's why there's the File.exists() method.
The path "help.chm" will be relative to the directory from which you started the JVM, which in your case appears to be C:/Users/toshiba/Documents/NetBeansProjects/test/
To get a path to the desktop, you need to use the absolute path of the desktop directory in Windows, which will be something along the lines of C:/Users/toshiba/Desktop/help.chm
You are attempting to read the file from (default folder)
C:/Users/toshiba/Documents/NetBeansProjects/test/
File doesn't exist but the would-be-file's path will be
C:/Users/toshiba/Documents/NetBeansProjects/test/
If you read the file from where it really is:
File f = new File("C:/Users/toshiba/Desktop/help.chm");
You will see that exists() returns true.
System.out.println(f.exists());
Then:
String f2=f.getCanonicalPath();

A multi-platform way to access jar located resources in java

I need some code that could get an InputStream from a resource stored in some path into a jar file, this is the test code:
String res =File.separatorChar+ "folder"+File.separatorChar+"file.txt";
InputStream is = ReadRes.class.getResourceAsStream(res);
System.out.println(is);
Into my jar I have the directory folder/file.txt, in linux it works but on Windows I get a null value for is . What should I do?
Always use / when fetching the resource.
The resource is not a File, and the path is represented by an URL which always has forward slashes.

Accessing a resource within a jar (working in Netbeans but not on command line)

I have a jar file with bundled resources (language model binary files) that need loading at run time. The directory structure within the jar is
tagger/app.class
tagger/models/stop/SentDetect.bin.gz
where SentDetect.bin.gz is a binary whos path is loaded into a thirdparty class (SentDetector) as a String parameter, i.e.
URL url = this.getClass().getResource("models/stop/SentDetect.bin.gz");
SentenceDetector sdetector = new SentenceDetector(url.getPath());
While it runs ok in Netbeans, when I try to run it as a jar from command line, I get a FileNotFound Exception at the constructor. I have double checked that the binary is included in the compiled Jar file.
I believe the solution would usually be to load the data in as an input stream using getResourceAsStream(), but this is not an option here, as the url is being passed as a String parameter to a third party constructor, which leads me to believe the problem is with how the url is being parsed to a String?
I have tried:
url.getPath();
url.getFile();
url.toURI().getPath();
url.toString();
and all are giving different paths to the file.
It sounds like that should be fine, if the binary is definitely in the right place and the jar file is definitely in the class path. (I assume it can find the class itself? I'd expect so, given that you're using this.getClass()).
One thing which might be causing issues is filename casing - when it's loading the file from the file system, if you're using Windows that'll be case insensitive; in a jar file it'll be case sensitive. Check the case in code matches the case in the jar file.
You can't access a resource in a Jar file via java.io.File. You should provide an alternate constructor for SentenceDetector which either accepts an InputStream rather than a String, or which accepts an URL and uses URL.openStream() to get an InputStream.

Categories

Resources