Why operations over Path realized in form of static methods? - java

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.

Related

Relative path vs absolute paths

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.

Java JNI Interface: Native functions relative file paths

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.

What is the equivalent to python equivalent to using Class.getResource() [duplicate]

This question already has answers here:
Way to access resource files in python
(4 answers)
Closed 9 years ago.
In java if I want to read a file that contains resource data for my algorithms how do I do it so the path is correctly referenced.
Clarification
I am trying to understand how in the Python world one packages data along with code in a module.
For example I might be writing some code that looks at a string and tries to classify the language the text is written in. For this to work I need to have a file that contains data about language models.
So when my code is called I would like to load a file (or files) that is packaged along with the module. I am not clear on how I should do that in Python.
TIA.
I think you may be looking for pkgutil.get_data(). The docs for this say:
pkgutil.get_data(package, resource)
Get a resource from a package.
This is a wrapper for the PEP 302 loader get_data() API. The package
argument should be the name of a package, in standard module format
(foo.bar). The resource argument should be in the form of a relative
filename, using / as the path separator. The parent directory name ..
is not allowed, and nor is a rooted name (starting with a /).
The function returns a binary string that is the contents of the
specified resource.
For packages located in the filesystem, which have already been
imported, this is the rough equivalent of:
d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()
If the package cannot be
located or loaded, or it uses a PEP 302 loader which does not support
get_data(), then None is returned.
I think you are looking for imp.load_source:
import imp
module = imp.load_source('ModuleName', '/path/of/the/file.py')
module.FooBar()
For Pythonistas who don't know, the behaviour of Java's Class.getResource is basically: the supplied file name is (unless it's already an absolute path) transformed into a relative path by using the class' package (since the directory path to the class file is expected to mirror the explicit "package" declaration for the class). The ClassLoader that was used to load the class in the first place then gets to transform this path string, by its own logic, into a URL object that could encode a file name, a location on the WWW, etc.
Python is not Java, so we have to approximate a few things and read intent into the question.
Python classes don't really explicitly go into packages, although you can create packages by putting them in folders with an additional __init__.py file.
Python does not really have anything quite like the URL class in its standard library; although there is plenty of support for connecting to the Internet, you're generally expected to just use strings to represent URLs (and file names) and format them appropriately. This is arguably an unfortunate missed opportunity for polymorphism (it would not be hard to make your own wrapper, though you might miss lots of special cases and useful functionality). Anyway, in normal cases with Java, you're not expecting to get a web URL from this process.
Python has a concept of a "working directory" that depends on how the Python process was launched. File paths are not necessarily relative to the directory where the "main class" (well, really, "main module", because Python doesn't make you put everything in a class) is found.
So what you really want, probably, is to get the absolute path on disk to the source file corresponding to the class. But that isn't really going to work out either. The problem is: given a class, you can get the name of the module it comes from, and then look up that name to get the actual module object, and then from the module object get the file name that the module was loaded from. However, that file name is relative to whatever the working directory was when the module was loaded, and that information isn't recorded. If the working directory has changed since then (with os.chdir), you're out of luck.
Please try to be more clear about what you're really trying to do.

Any way to get a File object from a JAR

I have a JAR file that contains an API that uses external model files. I would like to include the model files in the JAR itself so it easier to use for other developers. The API will accept a File object only, is there any way to do this? I have already tried the following, and they have failed:
Using class.getResourceAsStream(). This would work if the API accepted an InputStream.
Parsing the classpath and trying to build from the entries (the JAR will show as app.jar)
I suppose an option is to use getResourceAsStream and move the files to a permanent location on the HDD but, I do not like this option. There has to be something better, any thoughts?
Resources in a .jar file are not files in the sense that the OS can access them directly via normal file access APIs.
And since java.io.File represents exactly that kind of file (i.e. a thing that looks like a file to the OS), it can't be used to refer to anything in a .jar file.
A possible workaround is to extract the resource to a temporary file and refer to that with a File.
Note that generally APIs that try to handle files should be written to handle InputStream/OutputStream as well to allow this kind of operations to suceed.

Using the ClassLoader method to retrieve all resources under classes as Input Streams

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.

Categories