file.toURI() returning A Wrong value? - java

I work in a Java RCP application. I am doing the following lines of code:
File file = new File(location);
String filePath = file.toURI().toString();
Desktop desktop = Desktop.getDesktop();
desktop.browse((new URL(filePath)).toURI());
where location is a String.
When the value of location is: http://www.google.com,
file.toURI()
is appending "file:/C:/eclipse%203.7.2/eclipse/" to the value and hence it becomes
file:/C:/eclipse%203.7.2/eclipse/http:/www.google.com
But when the value is: C:\Program Files,
file.toURI()
is not appending anything and returning the same value correctly.
Is there a limitation related to paths starting with http:// or something.
Does anyone have any idea on this ?

We have 2 types of file locations: relative and absolute. When the location is something like C:\User in MS Windows or /home in Linux the location is absolute and there is no need to append something at the beginning of them! But when the location is http://google.com the program append your program location at the beginning of it.
I think you need to search about URI and URL. You used them incorrectly!

java.io.File works with file paths not URLs.
So it transforms the supplied initialization parameters into the representation that is your local file system supports.
"http://" means nothing to your local file system, it's just a file name (well, wrong file name but anyway).
In the first case with "http://www.google.com" it does not see disk drive letter in the supplied value so it is considered as relative path and current working dir absolute path added as a prefix ("user.home" env var if I'm not mistaken).
In the second case, you added an absolute path "C:\Program Files". It sees disk drive letter inside and there is no sense to add anything as a prefix.

Related

How to convert network path to URL in Java

I have literally searched the whole internet for this question but I have not found an answer. I have a file, in the network and I want to create an Itext image with it and for that, I have to convert its path to URL. The problem is when I use path.toURI().toURL() it appends my project path to the URL such that my URL ends up starting with C:/ which will not work.
Is there a way to just convert a string to file URL in java?
I have tried this:
String paths = "‪\\\\DESKTOP-A11F076\\Users\\Benson Korir\\Desktop\\walgotech\\passport.jpg";
String first = "file:" + paths.replaceAll("\\\\", "//").replaceAll("////", "//");
String second = "file://desktop-a11f076//Users//Benson Korir//Desktop//walgotech//passport.jpg";
System.out.println(first);
System.out.println(second);
The second string I have copied directly from the browser and it works fine. Funny this is these two strings output the same thing but the first string brings an error when I use it here:
Image image1 = Image.getInstance(second);
I am getting the error below:
java.io.FileNotFoundException: ‪\DESKTOP-A11F076\Users\Benson Korir\Desktop\walgotech\passport.jpg (The system cannot find the path specified)
If I got your requirement correctly, your path is a UNC file name, and that is the short form of an SMB path, with DESKTOP-A11F076 being the remote machine, and \Users\Benson Korir\Desktop\walgotech\passport.jpg being the path to the file on that machine.
If I am correct with that assumption, my understanding is that your URL have to look like this: smb://‪DESKTOP-A11F076/Users/Benson Korir/Desktop/walgotech/passport.jpg.
As far I remember is a Java java.io.File object capable to handle a UNC file name (this article implies that, too), but when translating it to a URI, it tries to make it absolute first, and there it fails in your case.
I usually avoid working on Windows whenever possible, therefore I have no environment to verify that.

Error message: The file "countries.geo.json" is missing or inaccessible

I am taking the Coursera OOP in Java class. In the module 4 assignment, I run the code that the course provides in EarthquakeCityMap.java,
and I get an error as "The file "countries.geo.json" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable.
Exception in thread "Animation Thread" java.lang.NullPointerException"
I tried to set countryFile as
"../data/countries.geo.json",
"data/countries.geo.json",
and the complete path of countries file,
but still didn't solve the problem.
//this error points to the code
private String countryFile = "countries.geo.json";
List<Feature> countries = GeoJSONReader.loadData(this, countryFile);"
//the countries file is saved in data folder.
Poject folder listing
"countries.geo.json" (unless changed in GeoJSONReader manipulates this path) will be relative to the compiled java .class files in the IntelliJ's project out folder.
If this in GeoJSONReader.loadData(this, countryFile); is a PApplet instance you can use sketchPath() to make that path relative to the folder from which the sketch runs:
List<Feature> countries = GeoJSONReader.loadData(this, this.sketchPath("data"+File.separator+countryFile));
The above snippet is based on an assumption so the syntax in your code might be slightly different, but hopefully this illustrates how you'd use sketchPath().
Additionally there's a dataPath() as well which you can test from your main PApplet in setup() as a test:
String fullJSONPath = dataPath("countries.geo.json");
println("fullJSONPath: " + fullJSONPath);//hopefully this prints the full path to the json file on your machine
println(new File(fullJSONPath).exists());//hopefully this prints true
If you specified the full path and it didn’t work, you probably forgot to escape the \ character with another backslash. The backslash character is special and needs to be doubled for windows path to be interpreted properly. For instance “c:\\users\\...”. You can also specify / instead of \ and it would work : “c:/users/...”
That said, the path resolution of a file when relative (IE not being absolute to the file system root) is relative to the working directory of the executed app. Typically, in an IDE without any special configuration, the working directory would be the root path of the project. So in order to get the relative file path resolved properly, you would have to specify the path as “data/countries.geo.json”.
You can also find out what path you are in when you run the app by doing a System.out.println(new java.io.File(“.”).getAbsolutePath()) and craft the relative path according to this folder.

ClassLoader.getResource returns odd path (maybe)?

When loading an asset such as a text file from the resources folder, the most common approach is to use ClassLoader to get the path:
String path = getClass().getClassLoader().getResource("file.txt").getPath();
You can then use any of the many readers that java has to read the content of that file. But for some reason, Paths.get(path) is not happy with the path:
byte[] content = Files.readAllBytes(Paths.get(path))
-> throws java.nio.file.InvalidPathException when executed
ClassLoader.getResource(...).getPath() is returning:
/D:/Projects/myapp/build/resources/main/file.txt
Paths.get() doesn't like it. Apparently the ':' after /D is an 'Illegal char'. (Note that the path seems correct, the file is actually there)
Which one is causing the problem? Is ClassLoader.getResource() returning an invalid path or is Paths.get() acting up over nothing?
Some time later
It seems that there are multiple different formats for paths in java. The various frameworks don't appear to completely agree on what is right and what is wrong, therefore there are various discrepancies between the paths that they create and accept.
In this example, Paths.get() was in fact not expecting the leading slash in the path:
/D:/Projects/myapp/build/resources/main/vertex.vs.glsl <- EVIL
D:/Projects/myapp/build/resources/main/vertex.vs.glsl <- OK
I suppose that the question now is: How do I sanitise file paths returned by ClassLoader.getResource() for use with Paths.get() properly? Are there any other differences between their two file path formats?
"the most common approach" is not necessarily the best :)
Take care which path you mean: ClassLoader.getResource() returns a URL, which can have a path component. However, this is not necessarily a valid file-path.
Note, that there is also a method Paths.get(URI) which takes a URI as parameter
The first slash in /D:/Projects/myapp/build/resources/main/file.txt just means, that this is an absolute path: see Class.getResource
I recommend, that you simply use ClassLoader.html#getResourceAsStream when you want to read a file
Update to answer comment: "So why does Paths.get() not accept the absolute path?"
Paths.get() does accept absolute paths.
But you must pass a valid (file-)path - and in your case you pass the URL-path directly (which is not a valid file-path).
When you call: getClass().getClassLoader().getResource("file.txt") it returns a URL: file:/D:/Projects/myapp/build/resources/main/file.txt
this URL consists of the schema file:
and the valid (absolute URL)path: /D:/Projects/myapp/build/resources/main/file.txt
you try to use this URL-path directly as a file-path, which is wrong
thus the Paths.get(String,..) method throws an InvalidPathException
To convert the URL path to a valid file-path you could use the Paths.get(URI) method like so:
URL fileUrl = getClass().getClassLoader().getResource("file.txt");
Path filePath = Paths.get(fileUrl.toURI());
// now you have a valid file-path: D:/Projects/myapp/build/resources/main/file.txt
Please, have a look at the result of getClass().getClassLoader().getResource("file.txt"). It's a URL. With getPath() then you just retrieve the path part of that URL, ignoring protocol and server part. Opening the path part as a file might work under certain circumstances (in the easy cases where file syntax and URL path syntax match), but don't do it in production code.
Why? When you leave your IDE and deliver your application as JAR or WAR, the resources will reside inside a ZIP-compressed file, and there will be no file "file.txt" that you can open, there's only an entry in a JAR or WAR file.
As #TmTron pointed out, I also recommend to use ClassLoader.getResourceAsStream(). That will work in all cases.

Relative to absolute path in java

I have have a file that I want to use in my project which is in the resources package
src.res
Following what was stated in this answer, I believe that my code is valid.
File fil = new File("/res/t2.nii");
// Prints C:\\res\\t2.nii
System.out.println(fil.getAbsolutePath());
The problem is that I that file is in my projects file not there, so I get an Exception.
How am I suppose to properly convert from relative path to absolute?
Try with directory first that will provide you absolute path of directory then use file.exists() method to check for file existence.
File fil = new File("res"); // no forward slash in the beginning
System.out.println(fil.getAbsolutePath()); // Absolute path of res folder
Find more variants of File Path & Operations
Must read Oracle Java Tutorial on What Is a Path? (And Other File System Facts)
A path is either relative or absolute.
An absolute path always contains the root element and the complete directory list required to locate the file.
For example, /res/images is an absolute path.
A relative path needs to be combined with another path in order to access a file.
For example, res/images is a relative path. Without more information, a program cannot reliably locate the res/images directory in the file system.
Since you are using a Java package, you must to use a class loader if you want to load a resource. e.g.:
URL url = ClassLoader.getSystemResource("res/t2.nii");
if (url != null) {
File file = new File(url.toURI());
System.out.println(file.getAbsolutePath());
}
You can notice that ClassLoader.getSystemResource("res/t2.nii") returns URL object for reading the resource, or null if the resource could not be found. The next line convertes the given URL into an abstract pathname.
See more in Preferred way of loading resources in Java.
validate with
if (fil.exists()) { }
before and check if it really exist. if not then you can get the current path with
System.getProperty("user.dir"));
to validate that you are starting fromt he proper path.
if you really want to access the path you shouldnt use absolut pathes / since it will as explained start from the root of your Harddisk.
you can get the absolut path of the res folder by using this what my poster was writte in the previous answer:
File fil = new File("res");
System.out.println(fil.getAbsolutePath());

filesystem.getPath() returns wrong path

This problem is driving me crazy. I have a file I would like to reach in my src/main/resources folder and I am trying to obtain the path via:
FileSystem fileSystem = FileSystems.getDefault();
Path path = fileSystem.getPath(AnalysisEngine.class.getResource("/models/10_NB_7dev_2.model").getFile());
However, I keep getting the following error:
Illegal char <:> at index 2: /C:/Users/...(the path is here)/models/10_NB_7dev_2.model
As you can see, the path returned has '/' before C:, which ruins everything. What is the reason and how could this be fixed? Is there an alternative with java.io package?
I am using Windows 8 - 64 bit OS, if it helps.
The URL returned by Class#getResource(String) contains a preceding /.
/C:/Users/...(the path is here)/models/10_NB_7dev_2.model
That's just how URLs work. Then the FileSystem tries to parse that, but it makes no sense to it that there is a : character in the mix, so it throws an exception. In other words, getPath() is trying to create a path, not a url. You cannot have a : character in a Windows (possibly linux as well) path, unless it is directly following the Drive name as the first two characters of the path string.
The solution here is not to use the path of a classpath resource. A classpath resource might not come from the filesystem directly, it might be inside a jar.
...(the path is here)/models/10_NB_7dev.model
in your code you put:
("/models/10_NB_7dev_2.model").
Are you meaning to put a _2.?
If you are not worried about using the default filesystem (e.g. if you aren't using an in-memory filesystem for testing) then you can do:
URI uri = AnalysisEngine.class.getResource("/models/10_NB_7dev_2.model").toURI();
Path path = Paths.get(uri);

Categories