Java: Does FileReader support finding files using strings with %20? - java

My apologies if this is too simple a question, I was unable to google it as it did not like searching for %20.
If I have a URL on which I use the getFile() method to obtain the path for a file I would like to open for processing. If the particular file resides in a directory that contains spaces, the path returned would contains %20 where the space should be.
Will a FileReader then be able to use the path as provided, or will I need to replace the %20 with a space?

You will need to use URLDecoder yourself. FileReader just uses the String it's handed, and rightly so - %20 is a perfectly valid character sequence in a file name, and if it were automatically converted you could not access files containing it.

Use URLDecoder.decode() to decode a path

If you downloaded the file, and saved it on local file system.
And you are using FileReader to read it
as
FileReader fr = new FileReader(new File(url.getFile()));
Yes File, can understand URL encoding. So you don't need to decoded it.
If you decoded it as others have suggested it will be more readable when
you print the file path.

Related

How do i convert paths that contain unc shares

If user has not mounted a remote drive and is just using the \\ syntax how do I convert such a path (\\nas) held in a String to a file in Java, sorry not really sure what you call this \\ naming.
Also is this windows specific, can it also be //
You can pass any valid file name to the constructor of a File and Java will handle that for you. e.g.
File input = new File("\\\\nas\\somefile.txt");
will work just fine. Note the escaped backslashs. Java can handle forward slashes just as well, so the above can be written as:
File input = new File("//nas/somefile.txt");
A filename like \\nas\somefile.txt is called a UNC path

Unable to read input file from bin

Errr guys, I wrote some code to read a simple input file in Java, everything works perfectly fine, however after the code is checked-in and when others try to run it, their binary couldn't find the file (eventhough the file is RIGHT THERE in their bin folder)!
java.io.FileNotFoundException: C:\blah\bin\com\common\PackageRFCs.properties (The system cannot find the path specified)
So in my workspace, I have the these structure and files:
com.test.test.java
com.common.Utility.java
com.common.PackageRFCs.properties
In my test.java, I am trying to read the properties file this way:
Class<com.common.Utility> dummy = com.common.Utility.class;
String propURI = dummy.getPackage().getName().replace('.','/') + "/PackageRFCs.properties";
String filepath = ClassLoader.getSystemClassLoader().getResource(propURI).getFile();
...
BufferedReader br = new BufferedReader(new FileReader(filepath));
// do some read line stuff here
The above code work perfectly fine under my Eclipse, but failed when others tried to run it. I thought maybe i had some dangling file in my bin, so i did a Project > Clean, and i am still able to run it perfectly fine... I also tried cleaning the other user's workspace as well, and they still couldn't read the file... WTF is going on?
I can't reproduce the problem on my end.
If you have a URL from getResource() you don't need to convert it to a filepath and open that with a FileReader (which won't work anyway, as the result of URL.getFile() isn't a native file path, it's simply a substring of the original URL). Just use .openStream() or call get{System}ResourceAsStream() in the first place
BufferedReader br = new BufferedReader(new InputStreamReader(
ClassLoader.getSystemResourceAsStream(propURI), "ISO-8859-1"));
(I've assumed ISO-8859-1 encoding because the file is named .properties and this is the standard encoding for Java property files, but if that is wrong then change the encoding to match the file)
But given the structure you've spelled out, it would be more robust to use
Utility.class.getResourceAsStream("PackageRFCs.properties")
which handles the package-to-path mapping for you automatically, as well as being able to handle cases when your classes are loaded by a classloader other than the system classloader.

Files, URIs, and URLs conflicting in Java

I am getting some strange behavior when trying to convert between Files and URLs, particularly when a file/path has spaces in its name. Is there any safe way to convert between the two?
My program has a file saving functionality where the actual "Save" operation is delegated to an outside library that requires a URL as a parameter. However, I also want the user to be able to pick which file to save to. The issue is that when converting between File and URL (using URI), spaces show up as "%20" and mess up various operations. Consider the following code:
//...user has selected file
File userFile = myFileChooser.getSelectedFile();
URL userURL = userFile.toURI().toURL();
System.out.println(userFile.getPath());
System.out.println(userURL);
File myFile = new File(userURL.getFile());
System.out.println(myFile.equals(userFile);
This will return false (due to the "%20" symbols), and is causing significant issues in my program because Files and URLs are handed off and often operations have to be performed with them (like getting parent/subdirectories). Is there a way to make File/URL handling safe for paths with whitespace?
P.S. Everything works fine if my paths have no spaces in them (and the paths look equal), but that is a user restriction I cannot impose.
The problem is that you use URL to construct the second file:
File myFile = new File(userURL.getFile());
If you stick to the URI, you are better off:
URI userURI = userFile.toURI();
URL userURL = userURI.toURL();
...
File myFile = new File(userURI);
or
File myFile = new File( userURL.toURI() );
Both ways worked for me, when testing file names with blanks.
Use instead..
System.out.println(myFile.toURI().toURL().equals(userURL);
That should return true.

Reading File In JAR using Relative Path

I have some text configuration file that need to be read by my program. My current code is:
protected File getConfigFile() {
URL url = getClass().getResource("wof.txt");
return new File(url.getFile().replaceAll("%20", " "));
}
This works when I run it locally in eclipse, though I did have to do that hack to deal with the space in the path name. The config file is in the same package as the method above. However, when I export the application as a jar I am having problems with it. The jar exists on a shared, mapped network drive Z:. When I run the application from command line I get this error:
java.io.FileNotFoundException: file:\Z:\apps\jar\apps.jar!\vp\fsm\configs\wof.txt
How can I get this working? I just want to tell java to read a file in the same directory as the current class.
Thanks,
Jonah
When the file is inside a jar, you can't use the File class to represent it, since it is a jar: URI. Instead, the URL class itself already gives you with openStream() the possibility to read the contents.
Or you can shortcut this by using getResourceAsStream() instead of getResource().
To get a BufferedReader (which is easier to use, as it has a readLine() method), use the usual stream-wrapping:
InputStream configStream = getClass().getResourceAsStream("wof.txt");
BufferedReader configReader = new BufferedReader(new InputStreamReader(configStream, "UTF-8"));
Instead of "UTF-8" use the encoding actually used by the file (i.e. which you used in the editor).
Another point: Even if you only have file: URIs, you should not do the URL to File-conversion yourself, instead use new File(url.toURI()). This works for other problematic characters as well.

Convert URL to AbsolutePath

Is there any easy way to convert a URL that contains to two-byte characters into an absolute path?
The reason I ask is I am trying to find resources like this:
URL url=getClass().getResources("/getresources/test.txt");
String path=url.toString();
File f=new File(path);
The program can't find the file. I know the path contain '%20' for all spaces which I could convert but my real problem is I'm using a japanese OS and when the program jar file is in a directory with japanese text (for example デスクトップ) I get the URL-encoding of the directory name,
like this:
%e3%83%87%e3%82%b9%e3%82%af%e3%83%88%e3%83%83%e3%83%97
I think I could get the UTF-8 byte codes and convert this into the proper characters to find the file, but I'm wondering if there is an easier way to do this. Any help would be greatly appreciated.
nt
URL url = getClass().getResource("/getresources/test.txt");
File f = new File(url.toURI());
If you were interested in getting Path from URL, you can do:
Path p = Paths.get(url.toURI());
File has a constructor taking an argument of type java.net.URI for this case:
File f = new File(url.toURI());
Another option for those who use Java 11 or later:
Path path = Path.of(url.toURI());
or as a string:
String path = Path.of(url.toURI()).toString();
Both methods above throw a URISyntaxException that can be safely ignored if the URL is guaranteed to be a file URL.

Categories