I have a java web application that reads files from the system, these files can be anywhere on the system.
I know if the file is in the webapp itself its always better to use relative path, but for files outside is it better to use absolute or relative? I just think using relative is a bit pointless, but many senior developers have suggested i use relative.
Would be interested in hearing thoughts, and what the practice is?
Normally, you should always use relative paths where possible. This is the best practice.
But if you can be absolutely (get it?) sure that file will stay there and is outside your actual application, you can refer it with an absolute path and it should be fine.
There are no real rules for when to use which... Id use it just for external stuff like this
The advantage you get with relative paths, obviously, is that its a lot more dynamic then using absolute paths.
It just depends on what you know. You have a webapp - that means that it's deployed on a server (like glassfish).
Up to the level of your servers folder it will be better to use relative paths - because you know the file structure up to that point and can localise everything without extra knowledge about the rest of the filesystem.
For files outside that you can't guarantee anything (it's perfectly legal to put and move server installation absolutely anywhere on the system) so absolute paths will be a more flexible choice.
Related
I am handling below way to work with files.
1st Approach:
I am keeping my files in D:\Projects\JavaProjects\LearnCucumber\src\test\resources\
-With the help of ClassLoader, I am getting the path and working on files
ResourceUtils.class.getClassLoader().getResource(".").getPath();
2nd Approach:
Now, I keep file in D:\Projects\JavaProjects\LearnCucumber\BrowserDrivers\
using System.getProperty("user.dir") I am dealing with files in this approach.
Now Which approach is efficient, when we run our code in different platform(windows,linux) in terms of handling files. Does it really makes difference?
Try to avoid working with files on the filesystem as those are usually less portable from one operating system to the next one. Also if you put files at certain locations other users of your software need to have those files available at the same location as well, whereas with your approach #1 you can ship these files directly with your application (packaged as jar) and access it from the classpath easily.
Getting resources for Java projects has always been fairly confusing to me, as the documentation doesn't explain it very well in my opinion, and I end up having to re-learn it every time I need to use it in a project. Most recently, using JavaFX, I was trying to load an image. The constructor requires a string representing the file path. I had come up with a very hacky method of doing this in the past, but I recently came across this StackOverflow post, and the accepted answer shows a very simple way of referencing the top level of the Eclipse project so that I can access source folders in the build path and easily locate my image files.
Is there a name for this particular delimeter? Are there other delimeters like it? Would there be problems using this notation when running this code in an executable JAR?
Any information would be greatly appreciated. And if this isn't the best way to approach this and someone could give me an adequate, simple explanation on how to do this in the future or a link to an article that explains it well, that would be great.
You can get resources using a relative path or an absolute path. Relative paths start from the "working directory", which is the directory your application runs from. An absolute path is unambiguous. The working directory is checked before the classpath. This is what is used in places like
new File(filepath).
When you run Java, there is also the classpath to consider. Another way some people look for resources is
ClassLoader.getResource(String)
and
ClassLoader.getResourceAsStream(String)
The ClassLoader can accept the String as a relative path and will check each location along the classpath.
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream(java.lang.String)
People get results by putting their files within the src folder because that usually gets copied over to the place where the class files are generated, which is included on the classpath.
The "top level" that you speak of is the working directory. Eclipse sets the working directory to the project root by default.
The relevant wikipedia page covers the file: scheme nicely.
But we live in a messy world, and various pieces of software may conform to older standards, or not conform completely with any standards, or may include support for alternate syntaxes. Understanding the correct syntax to use with a particular software system is unfortunately not always straightforward.
I am having problems with relative file paths that native functions use. When I call native C function from Java code, I get segmentation fault due to null file pointer. The only thing that works is to change these paths into absolute file paths, which is not solution for me. Is there any way to set root directory for native functions or to use Java project root folder to navigate through directories, or the absolute path is the only way?
Java does not have a way to change the working directory.
This is because the Java developers consider changing the working directory to create more problems than it solves. specifically:
It would be global mutable state. Global mutable state makes it harder to isolate parts of the application from each other.
It would be prone to race conditions (another side effect of being global mutable state).
It would not have a significant benefit. Everything that you could do by changing the current directory you can already do with absolute paths.
Your C code will need to use absolute paths.
Alternatively, if you are willing to write additional C code, your C code could call the operating system's chdir function directly. This may be dangerous, as the JVM is not designed for this possibility.
I solved the problem! Solution is using File.getAbsoluteFilePath() function, and passing it to native C function. It can be used for finding absolute path of shared library also, which makes application platform independent. C code can navigate through it's directories like before bounding with Java code.
Do you work in Linux?
in Linux,you can add the path
$LD_LIBRARY_PATH=.so file path
to the ~/.bashrcfile and then reboot..
If you work with windows, you can put the .dll file in the path that as the .class file path.
IMHO, path.delete() looks a little better than Files.delete(path). But developers of java.nio.file package preferred to realize operations over Path in form of Paths's static methods. Why?
It are utilitiy implementations, a design pattern as in Collection/Collections, File/Files, Path/Paths. Paths can handle different (virtual) "file" systems, like a zip file system. Hence a Path is associated with a file system, and a delete would delegate nevertheless to the file system delete. For instance:
For a zip file system view can have File path c:\data\x\y zip path relative x/y. You can move/rename/copy between paths. Having file operations reside in Path would be pure delegating calls.
They chose to let Path be a pure data structure even more than File, a bit like URL.
So there is some code design justification. But agreed, having several ~s classes, maybe used intermixed (Path+File+Paths+Files), does not make for a clean API style design.
Because, as the Javadoc states, a Path is
An object that may be used to locate a file in a file system. It will
typically represent a system dependent file path.
It's not actually a file, it just describes the path to the file. So there's nothing to delete or rather deleting doesn't make sense on a path. It only makes sense on a file.
My problem is one that you would think is quite common, but I haven't so far managed to find a solution.
Building a Java web app under Tomcat 5.5 (although a requirement is that it can be deployed anywhere, like under a WebLogic environment, hence the loading resources as streams requirement). Good practice dictates that resource files are placed under WEB-INF/classes and loaded using the ClassLoader's getResourceAsStream() method. All well and good when you know the name of the resource you want to load.
My problem is that I need to load everything (including recursively in non-empty sub-directories) that lives in a subdirectory of classes.
So, for example, if I have the following under WEB-INF/classes:
folderX/folderY
folderX/folderY/fileA.properties
folderX/fileB.properties
I need the fileA.properties and fileB.properties classes to be loaded, without actually knowing their names before the application is started (ie I need the ability to arbitrarily load resources from any directory under WEB-INF/classes).
What is the most elegant way to do this? What object could I interrogate to find the information I need (the resource paths to each of the required resources)? A non-servlet specific solution would be best (keeping it all within the class loading framework if possible).
Thanks in advance!
As far as I am aware, there is no such ability, since the classloader only attempts to load things it is asked for. It doesn't pre-fetch all items on the classpath, or treat them as a directory structure.
The way I would solve the problem is create a directory listing in a text file of all relevant resources at build time and include that in the war, and then walk it through that way.
You can do that with some tricks :)
Get the resource as URL, extract the protocol :
file protocol - get the URL path and you have a folder, scan for files.
jar/zip protocol - extract the jar/zip path and use JarFile to browse the files and extract everything under your path/package.