read / write Files in project folder - java

Hi I was wondering how to access files in the project folder in java/maven, i have thought about using src/main/resources, but i have been told it is a bad idea to write to files in this directory, and should only be used in configuration for the project, So i have created a new non source folder but i was wondering if there is a way to access this file in java without giving an absolute path, as i need to use it in different env. any help or other suitable suggestions would be great here thanks. i will be writing to the files at runtime.
EDIT:
i am using this to acces the file:
private static final String ACTUAL_VALUES ="verification/actualCounterValues.csv";
where verification is a folder i have created in my project

As i understand you, your goal is to access a file from within your app, without hardcoding a relative path because you're going to run it on different environments.
The first thing you may have to solve is to decouple the file-reference from your app - because if you move your app it must adapt to the new environment.
You may solve that by putting an absolute file-reference into the system-environment (which is accessible through the System.getenv() method). Another way could be to deliver the file-path as command-line-argument.
After that you have to specify when which running instance of your app will access the file. If your application runs separated in the maven and a production environment - everything is fine with using relative paths in the maven-project. The production-app will then generate and use its own file in its environment.
If they must share the file, you have to provide physical access from both environments to that file-path, after that you may access that file with separate absolute paths (delivered through cli-args or system-properties) or with "hard coded" relative paths, which access a file-link (which point to that absolute file).
But i must discourage you from using any hardcoded configuration-specific variables for ongoing maintenance reasons.
And if these two application-instances will access both one single file, you should also be aware of possible concurrency difficulties (especially in the filesystem - see that post).

Related

tuProlog - using multiple files with consult - can't get engine to load additional files with consult(otherFile.pl)

Edit: Clarity - the main .pl file loads, it's all the subfiles that it has been told to load which don't load. (all the consult('subfile.pl').)
I have a Java project that uses tuProlog. It calls a theory as:
Theory theory = new Theory(":-consult('main.pl').");
engine.setTheory(theory);
This is as per the manual.
file.pl exists in the same folder as other prolog files.
Inside of main.pl, I have further
consult('otherfile.pl').
statements to load additional files (several).
The folder structure is:
src/main.pl
src/Prolog_Files/otherfile.pl (multiple)
src/main/java/JavaStuff
I can't get the engine to load the theories that I've told it to consult inside of the main file.pl
I have tried: giving it absolute path instead of just filename.
moving files around.
I'm wondering if there is something about usage of tuProlog I'm not understanding?
The theory works when loaded with:
Theory theory = new Theory(new FileInputStream(url_of_file)).
However, this is causing me issues when building the jar, as it can't find the file location.
Am I attempting to load the file correctly? Are my consults inside of the main .pl file correct?
Could someone please post an example of how this should be done if not? The manual doesn't elaborate very much on this topic.
Thanks
The manual is slightly outdated in parts - it says to use consult/1, whereas elsewhere it states that consult/1 is deprecated, whereas include/1 is the replacement.
Secondly, when using 2p.jar, it reads Prolog files from the Project root as its root. When creating a jar, 2p.jar cannot be inside of the project jar. They should be in relative folders, and 2p.jar reads Prolog files with the location of 2p.jar as root. It doesn't seem that it can read inside of project jar.
Hopefully that's clear enough!

Accessing folder in android

I am working on an android app in which I need to detect the language of user's input text.
So using Stackoverflow I found a recommendation of using a java library called langdetect which requires reading languages profiles.
I was able to create a simple plane java project, by adding a directory (folder) inside the java project called "profiles" which contains all the languages profiles.
I couldn't make this work in android since the only 2 ways I know of accessing files in android either by adding the desired files inside "assets" or "rec/raw" but I keep getting error saying file not found.
The method from langdetect jar file that requires reading profiles is the following
String path = "profiles";
DetectorFactory.loadProfile(path);
the above code works in plain java.
Any help guys.
I used the following
Uri.parse("android.resource://com.my.package.my.app/raw");
file:///android_asset
classLoader.getResource("profiles");
and many others in the same style.
The problem is that I don't need to access specific file per say, the only thing I need is a path to the folder that contains the languages profiles, the folder contains 53 files for 53 languages.
path is relative. It does not make sense in Android. You should refere the Internal/External storage with Absolute Path. If you put your data inside the sdcard, for instance, you can retrieve the Absolute Path with Environment.getExternalStorageDirectory(). If you want to embeded your data inside the apk, using the assets or raw folder, you need the AssetsManager in the former case, getResources() in the latter.

Storing configuration file of an application in OS independent path

I am writing an application (basically eclipse plugin), so there are few combo-box, drop-downs etc, which I am getting values for them dynamically via XML file. My doubt is which is the best way to store these files in a particular directory so that it can be read in both Windows as well as Linux.
Initially I tried to create a config path under {eclipse.home.location} like:
String finalPath = System.getProperty("eclipse.home.location") +"/myAppConfig";
and store all of my plugin's configuration there (not only configuration but few helper jars which I programatically read in my plugin). But there is a probabilty that Eclipse installation maybe in shared location and user may not have write access to it.
I also tried to store it in a program files directory using:
System.getenv("ProgramFiles");
But this fails under non-windows environments. So my question is can anyone shed a light on this so that I can store in some common directory where it is valid for both windows and linux?
Kindly let me know if my wordings are confusing. Or is it possible to store my config files under plugins directory and get the path like this /plugins/myConfigDir ?
Try using the getStateLocation() method in Plugin.
That will give you an IPath that points to a user specific workspace location.

Why does an image path no longer work once I compile my java files into a jar file?

I have a relatively basic java program which uses a system tray icon. The path I was using while writing the code is as follows "../images/logo.png". However, when I compile it into a jar file, the image does not show up in the system tray. Instead, if I change the path to "./images/logo.png", then the image shows up in the system tray when it's in the jar file form, but not while I'm testing.
It's not a major issue. However, I am curious to know why this inconsistency occurs.
When you package your program into a .jar file, your build is most likely copying the image into the same directory as the .jar file. However, when debugging in your ide, your image file lies one directory below.
Another possibility is that you are simply setting your Working Directly differently in the two scenarios.
Incidentally, you might be interested in embedding the image in your jar file, see:
https://stackoverflow.com/a/1096491/24954
This answer depends on two things. If the image file is embedded or not.
Embedded Resource
Once you have Jar'ed your application and the images are emebbed inside the application, normal file access methods will no longer work.
Trying to do something like...
new ImageIcon("../images/logo.png");
or
new File("../images/logo.png");
Won't work. This is because the resource is no longer a file within the context of the file system (it's actually a Zip entry in the Jar).
Instead, you need to use Class#getResource which will return a URL to the embedded resource.
new ImageIcon(getClass().getResource("../images/logo.png"));
Will work better. In general though, it is recommended to use an absolute path to the resources new ImageIcon(getClass().getResource("/images/logo.png")); as it's generally more difficult to break (IMHO)
External Resource
The path to the image is relative to the execution point of the application.
In development, you may have had to move up a directory (out of the src folder presumably) to find the image resource. This will mean that you will need to store you Jar file in a folder that would require it step up one level before it could find the image resource.
If you can, it's generally better to embedded the resource within the Jar where possible. It makes it easier to deploy as you reduce the number of files you need to package and makes it (a little) harder for the user to mess with it ;)

Simulate app.config for Java?

I know that you can use java.util.Properties to read Java properties files.
See: Java equivalent to app.config?
Is there a standard place to put this file? In .NET we put application.exe.config in the same directory as application.exe. The application looks for it here by default.
Java can be made to look for a properties file in the class path but I am struggling to understand the filename/path structure to use and how to use either a standard .properties format or XML format file.
Assuming I have an API packaged in org_example_api.jar (the root package is org.example.api). I don't want to put the properties file inside the jar as it should be editable by the user. I want the user to be able to put the required configuration properties in either a .properties or .xml file somewhere relative to the classpath so I can find it without needing to know anything about the ir file system structure.
Will this work on all systems:
/classpath/org_example_api.jar
/classpath/org/example/api/config.properties OR
/classpath/org/example/api/config.xml
Code:
java.util.Properties = ? //NEED SOME HELP HERE
This purely depends on the type of application you are developing.
1) If it is a web application the best place is inside the WEB-INF/classes/ folder.
2) If you are developing a standalone application there are many approaches. From your example I think the following structure will work.
/<dist>/org_example_api.jar
/<dist>/config.xml
/<dist>/run.sh
In the run.sh you can start the java application providing the current directory also in the classpath. Something like this.
java -cp .:org_example_api.jar ClassToExecute
3) If it is an API distribution it is up to the end user. You can tell the user that they can provide the config.xml in the classpath which should follow some predefined structure. You can look at Log4J as an example in this case.
The world is wide open to you here. The only best practice is what works best for you:
Whatever program the user is running can require the path to the properties file as an argument
Your application can be configured to look in the current directory for config.properties.
If the file can't be found, you could maybe fall back to the user.home directory, or fall back to wherever your application is installed.
Personally I usually have my applications attempt to read properties files from the classpath - but I'm not in a world where I have end-users update/change the file.
Whatever option you choose, just make sure you clearly document it for your users so they know which file to edit and where it needs to be!
You can put the properties file in a directory or JAR in your CLASSPATH, and then use
InputStream is = getClass().getResourceAsStream("/path/goes/here");
Properties props = new Properties();
props.load(is);
(I noticed you mentioned this in your OP, but others may find the code useful.)

Categories