Canonical path not working - java

So I'm trying to use the canonical path to access a sound file, but it does not seem to work. Here is my code:
// load wave data from buffer
WaveData wavefile = WaveData.create("/Users/spex/NetBeansProjects/spaceinvaders/src/spaceinvaders/spaceinvaders/" + path);
It appears that it is trying to get the path from the location of the class path. Is there a way to let it know that I want to input the canonical path rather than a local one?

Try using a URL instead, as stated in the javadocs:
WaveData wavefile = WaveData.create(new URL("file:/Users/spex/NetBeansProjects/spaceinvaders/src/spaceinvaders/spaceinvaders/" + path));
Alternatively, create an input stream from your file, and the call WaveData.create(inputStream).

Related

Why can I get a valid url from getClass().getResource(), but the url that is returned creates a file that doesn't exist

I am trying to load some data into an AWS lambda and am using getClass().getResource() to do so. This returns a nice URL that in logs seemingly prints out a plausible url; however, when I try and make a file based on that path, I get a file that when I call .exists() returns false.
If I run the code bellow, the first print statement gives "returns exists: false"
Meanwhile, the second print statement gives something around the lines of "test path: /file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
File test = new File(cFile);
System.out.println("exists: " + test.exists());
System.out.println("test path: " + test.getAbsolutePath());
Not sure why this would be. If Java finds a file, then I would assume that the file exists...
Short answer: don't assume that the "path" of a URL is a file system pathname.
I am trying to load some data into an AWS lambda and am using getClass().getResource() to do so. This returns a nice URL that in logs seemingly prints out a plausible url;
Yes. (It would be nice if you showed us what the original URL looks like ... though I can guess.)
However, when I try and make a file based on that path, I get a file that when I call .exists() returns false.
OK, unless the URL has the protocol "file:", I would NOT expect that to work.
The path in a URL is a path that is intended for the protocol handler to resolve. The idea is that you use URL::openStream to open a stream to the resource named by the URL and then read it. The protocol handler takes care of interpreting the path (etc) and setting up the stream.
For a "file:" URL, the protocol handler will resolve the path in the file system, and provide you a stream to read the file.
For a "http:" URL, the protocol handler establishes a connection to the server, sends a GET request, and returns you a stream to read the response body.
For a "jar:" URL, the protocol handler opens the JAR file, finds the entry within the JAR file, and hands you a stream to read it.
And so on.
If you look at these, it is only in the "file:" case that there is a reasonable expectation that treating the path component of the URL as a file system pathname could work.
Looking at the pathname in your question:
file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
I surmise that the original URL was:
jar:file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
So what that says to the "jar:" protocol handler is:
Find the resource identified by the URL "file:/var/task/lib/MyLambda-1.0.jar"
Open it as a JAR file stream
Find the entry "/com/my/package/folders/file.end" in the JAR file's namespace
Open a stream to read that entry's content.
The JAR file protocol handler knows how to do that. But (clearly) the File class doesn't ... because that "path" is not a file system pathname.
How you solve this depends on what you really need.
If you just need a stream to read the resource, use getClass().getResourceAsStream(...) instead.
If it must be a file in the file system, you may have to get hold of the stream (see above), copy it to a temporary file, and use a File for the temporary file.
If you are doing the because you want to write to the "file", I would suggest that you give up on that idea. It is a bad idea for an application to try to update its resources. And in some cases it simply won't / cannot work.
Is your File test = new File(cFile), Is your cFile made correctly with a proper path? Maybe the last print statement is just picking up on the incorrect path you made? But in reality you don't actually have a file there. Have you checked manually?

Generate URI from String provided by user via command line argument

This is such a simple question, I'm sure the answer is out there and I'm simply not searching with the proper lingo. I'm new to Java, using Java 8, and want to learn how to properly handle this, rather than rigging it together.
The application takes in arguments via command line.
$ MyApp /home/user/thefiletheywant.me
I have tried the following:
// Missing Scheme, I know I can just force ("file:" + args[0]) but is that proper?
URI fileIn = new URI(args[0]);
// I've learned this is the same thing as above
URI fileIn = URI.create(args[0]);
I've seen examples that take the string, check with File.Separator to verify it is "/" and if not, replace it, then simply tack on "file:" in front. Which, again, seems sloppy.
What if the user added "http:"?
What if the user specifies a full path or a path relative to the directory they are currently in?
Do the builtin functions verify the path is proper? I'm aware of file.isFile() and file.exists(), which I can check myself easy enough.
If I knew exactly where the file was every time, of course the URI.create would be fine. But for future education, I want to know how to properly handle this very simple scenario. Please forgive me if in my searches I've simply somehow missed what I suspect is an easy solution.
You could just create a File object in java, which is OS-independent (Windows uses backslash for instance), check if it exists, and use the handy toURI() method on it, to create a valid URI object.
File myFile = new File(args[0]);
URI fileUri = null;
if(myFile.exists()) {
fileUri = myFile.toURI();
}

Java parse File-path with different working directory

I have a file which contain several paths, like . (relative) or /Users/...../ (absolut). I need to parse the paths that are relative to the directory of the file that contains the paths and not the working-directory and create correct File-instances. I can not change the working directory of the Java-Program, since this would alter the behaviour of other components and i also have to parse several files. I don't think public File(String parent, String child)does what i want, but i may be wrong. The documentation is quite confusing.
Example:
file xy located under /system/exampleProgram/config.config has the following content:
.
/Users/Name/file
./extensions
i want to resolve these to:
/system/exampleProgram/
/Users/Name/file
/system/exampleProgram/file/
So, I am going to assume that you have access to the path of the file you opened (either via File.getAbsolutePath() if it was a File descriptor or via a regex or something)...
Then to translate your relative paths into absolute paths, you can create new File descriptions with your opened file, like so:
File f = new File(myOpenedFilePath);
File g = new File(f, "./extensions");
String absolutePath = g.getCanonicalPath();
When you create a file with a File object and a String, Java treats the String as a path relative to the File given as a first argument. getCanonicalPath will get rid of all the redundant . and .. and such.
Edit: as Leander explained in the comments, the best way to determine whether the path is relative or not (and thus whether it should be transformed or not) is to use file.isAbsolute().
Sounds like you probably want something like
File fileContainingPaths = new File(pathToFileContainingPaths);
String directoryOfFileContainingPaths =
fileContainingPaths.getCanonicalFile().getParent();
BufferedReader r = new BufferedReader(new FileReader(fileContainingPaths));
String path;
while ((path = r.readLine()) != null) {
if (path.startsWith(File.separator)) {
System.out.println(path);
} else {
System.out.println(directoryOfFileContainingPaths + File.separator + path);
}
}
r.close();
Don't forget the getCanonicalFile(). (You might also consider using getAbsoluteFile()).

Android get file using path (in String format)

My app needs to get an existing file for processing. Now I have the path of the file in String format, how can I get the File with it? Is it correct to do this:
File fileToSave = new File(dirOfTheFile);
Here dirOfTheFile is the path of the file. If I implement it in this way, will I get the existing file or the system will create another file for me?
That's what you want to do. If the file exists you'll get it. Otherwise you'll create it. You can check whether the file exists by calling fileToSave.exists() on it and act appropriately if it does not.
The new keyword is creating a File object in code, not necessarily a new file on the device.
I would caution you to not use hardcoded paths if you are for dirOfFile. For example, if you're accessing external storage, call Environment.getExternalStorageDirectory() instead of hardcoding /sdcard.
The File object is just a reference to a file (a wrapper around the path of the file); creating a new File object does not actually create or read the file; to do that, use FileInputStream to read, FileOutputStream to write, or the various File helper methods (like exists(), createNewFile(), etc.) for example to actually perform operations on the path in question. Note that, as others have pointed out, you should use one of the utilities provided by the system to locate directories on the internal or external storage, depending on where you want your files.
try this..
File fileToSave = new File(dirOfTheFile);
if(fileToSave.exists())
{
// the file exists. use it
} else {
// create file here
}
if parent folder is not there you may have to call fileToSave.getParentFile().mkdirs() to create parent folders

Specifying a relative path in File in Java

I'm uploading images using Spring and Hibernate. I'm saving images on the server as follows.
File savedFile = new File("E:/Project/SpringHibernet/MultiplexTicketBooking/web/images/" + itemName);
item.write(savedFile);
Where itemName is the image file name after parsing the request (enctype="multipart/form-data"). I however need to mention the relative path in the constructor of File. Something like the one shown below.
File savedFile = new File("MultiplexTicketBooking/web/images/" + itemName);
item.write(savedFile);
But it doesn't work throwing the FileNotFoundException. Is there a way to specify a relative path with File in Java?
Try printing the working directory from your program.
String curDir = System.getProperty("user.dir");
Gets you that directory. Then check if the directories MultiplexTicketBooking/web/images/ exist in that directory.
Can't count the number of times I've been mistaken about my current dir and spent some time looking for a file I wrote to...
It seems the server should offer functionality as might be seen in the methods getContextPath() or getRealPath(String). It would be common to build paths based on those types of server related and reproducible paths. Do not use something like user.dir which makes almost no sense in a server.
Update
ServletContext sc=request.getSession().getServletContext();
File savedFile = new File(sc.getRealPath("images")+"\\" + itemName);
Rather than use "\\" I'd tend to replace that with the following which will cause the correct file separator to be used for each platform. Retain cross-platform compatibility for when the client decides to swap the MS/ISS based server out for a Linux/Tomcat stack. ;)
File savedFile = new File(sc.getRealPath("images"), itemName); //note the ','
See File(String,String) for details.
You could get the path of your project using the following -
File file = new File("");
System.out.println("" + file.getAbsolutePath());
So you could have a constants or a properties file where you could define your path which is MultiplexTicketBooking/web/images/ after the relative path.
You could append your path with the path you get from file.getAbsolutePath() and that will be the real path of the file. - file.getAbsolutePath() + MultiplexTicketBooking/web/images/.
Make sure the folders after the Project path i.e. MultiplexTicketBooking/web/images/ exist.
You can specify the path both absolute and relative with File. The FileNotFoundException can be thrown because the folder might be there. Try using the mkdirs() method first in to create the folder structure you need in order to save your file where you're trying to save it.

Categories