How to read configuration file using absolute path? - java

I have a configuration file from which I have to read some properties. This configuration file exists in diferent locations but has the same name. I am able to read a configuration file, but only one from my project. I used the following code:
Properties prop = new Properties();
String propFileName = "config.properties";
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
try {
prop.load(inputStream);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
if (inputStream == null) {
try {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have to open the config file using the full path so instead of propFileName="config.properties" to insert the absolute path to the config file. The config file can't be opened if I use the absolute path.
How can this be done ?

InputStream inputStream = new FileInputStream("path");
will open a file with an absolute path.
Note: This will only work for a file, it will not work for anything included in a plugin jar.

You can use FileInputStream for locating config file outside of your project path.
Properties prop = new Properties();
InputStream input = new FileInputStream("/home/ubuntu/Desktop/sample.properties");
prop.load(input);
System.out.println(prop.get("test"));
When specifying path we need give file name with extension.

Related

How to place a file for jar and read it with FileInputStream

This is the code
public static void readCharacters() {
try (FileInputStream fi = new FileInputStream("main/characters.dat"); ObjectInputStream os = new ObjectInputStream(fi)) {
characterList = (LinkedList<Character>) os.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
This is the structure:
And this is the Error
java.io.FileNotFoundException: main\characters.dat (The system cannot find the path specified)
What I want is to include the characters.dat file in my jar, and be able to read and write it while the program runs. Is there a different way to write the path? or to put the .dat file in a different position.
Also the writing method:
public static void writeCharacters() {
try (FileOutputStream fs = new FileOutputStream("main/characters.dat"); ObjectOutputStream os = new ObjectOutputStream(fs)) {
System.out.println("Writing Characters...");
os.writeObject(characterList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
You can't. You can do one or the other. JAR files are not file systems, and their entries are not files. You can read it with an input stream:
InputStream in = this.getClass().getResourceAsStream("/main/characters.dat");
Check it for null before proceeding.
The jar is for read-only resources. You can use it for the initial file, as a kind of template.
Path path = Paths.get(System.getProperty("user.home") + "/myapp/chars.dat");
Files.mkdirs(path.getParentPath());
if (!Files.exists()) {
try (InputStream in =
Controller.class.getResourceAsStream("/main/characters.dat")) {
Files.copy(in, path);
}
}
The above copies the initial.dat resource from the jar to the user's home "myapp" directory, which is a common solution.
System.getProperty("user.dir") would the running directory. One can also take the jar's path:
URL url = Controller.class.getResource("/main/characters.dat");
String s = url.toExternalForm(); // "jar:file:/.... /xxx.jar!/main/characters.dat"
From that you can also construct the jar's directory. Mind to check Windows, Linux, spaces and such.
URL url = Controller.class.getProtectionDomain().getCodeSource().getLocation();
The solution above risks a NullPointerException, and works a bit differenly running inside the IDE or stand-alone.
Important note:
When using getResourceAsStream, you must start your path by slash /, this specifies the root of your jar, .getResourceAsStream("/file.txt");
In my case my file was a function argument, String filename, I had to do it like this:
InputStream in = this.getClass().getResourceAsStream("/" + filename);

Issue with file path in Java/Liferay

I have tried in multiple ways to load the property file from the resource folder.
Every time, I'm getting a file not found exception. My code is as follows:
Properties prop = new Properties();
FileInputStream inputStream = new FileInputStream("/resource/excelfilepath.properties");
prop.load(inputStream);
String path = prop.getProperty("excelPath");
System.out.println("Excel File Path "+ path);
My project structure looks as follows,
What is the needed structure of the file path literal?
I don't think that you really want to read a ....properties file from web resources. That way the content is visible to all users that access your server - as long as you don't hide it explicitly in web.xml.
It's much more common to put it into the classpath next to your accessing class. That way you can access it with the classloader and it is not visible to the webusers anymore:
Properties prop = new Properties();
prop.load(CreateUser.class.getResourceAsStream("excelfilepath.properties"));
But as you are using Liferay, you should use its configuration as well. Just add the property UserCreationPortlet.excelPath to your portal-ext.properties and use:
String path = PrefsPropsUtil.getString("UserCreationPortlet.excelPath", defaultPath);
You need to tell to the server where your root folders are :
With Tomcat : in the catalina.properties
append the properties shared.loader with yours.
With Jboss : Edit jboss-service.xml in your conf folder
<classpath codebase="${jboss.home.url}/server/default/lib//proprietes/rootFolder" archives="*"/>
I would advice to create a classe to load your properties :
Like :
public static Properties charger(Class<?> pClass, String pFilename) {
Properties aProperties = null;
try {
InputStream aIs = null;
File aFile = new File(pFilename);
if (!aFile.isAbsolute()) {
aIs = pClass.getClassLoader().getResourceAsStream(pFilename);
if (aIs == null) {
return null;
}
} else if (!aFile.exists()) {
return null;
}
if (aIs == null)
aIs = new FileInputStream(aFile);
InputStreamReader reader = new InputStreamReader(aIs, "UTF-8");
aProperties = new Properties();
aProperties.clear();
aProperties.load(reader);
reader.close();
aIs.close();
} catch (FileNotFoundException e) {
LOG.error("Catch FileNotFoundException : ", e);
} catch (IOException e) {
LOG.error("Catch IOException : ", e);
}
return aProperties;
}
Then call your new class with the property that you wish :
protected static final Properties property = ChargeurProprietes.charger( .class,"PATH");
property.getProperty(NAME OF YOUR PROPERTY);

Why isn't a new created file local?

I have the problem, that I create a new file in a Java program, but I always get an exception, that the new created file is not local, when I try to open it on the eclipse project explorer view.
The code where I create it is as follows:
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IProject project = workspaceRoot.getProject(projectName);
FileUtil myFile = new FileUtil();
if (!project.getFile(FILE_NAME).exists()) {
IFile newFile = project.getFile("conf.txt");
FileInputStream fileStream = null;
try {
String temp = project + "/conf.txt";
temp = temp.substring(2);
fileStream = new FileInputStream(temp);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
newFile.create(fileStream, false, null);
} catch (CoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// create closes the file stream, so no worries.
try {
myFile.writeTextFile(FILE_NAME, "Seconds", output);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
FileUtil is a class which only implements the methods write and read for the file.
The Exception I get when I try to open it begins with:
org.eclipse.core.internal.resources.ResourceException: Resource '/ProjectE1/conf.txt' is not local.
at org.eclipse.core.internal.resources.Resource.checkLocal(Resource.java:353)
at org.eclipse.core.internal.resources.File.getContentDescription(File.java:264)
at org.eclipse.core.internal.propertytester.FilePropertyTester.testContentType(FilePropertyTester.java:108)
I somehow have to get a relative path during the runtime. Because I am opening a new instance of eclipse in the program, where I can see the Project in the Project Explorer but can't open the conf.txt file because it is not local.
It looks like your resource is an absolute path to /ProjectE1/conf.txt, I'm confused why you are not using java.io.
This will help you understand relative paths, I think this may be where you are wanting to put your conf file.
File file = new File("conf.txt");
if(!file.createNewFile()){
//err
}
System.out.println(file.getAbsolutePath());
I had similar issue. This is how I fixed.
First created file in local file system (using java.io)
Did project refresh
Reload the file
File file = new File(project.getWorkspace().getRoot().getLocation() + project.getFullPath().toString() + "/relative_path_of_my_file");
file.createNewFile();
project.refreshLocal(IProject.DEPTH_INFINITE, null);
keywordFile = project.getFile("/relative_path_of_my_file");

Create file in specified directory

Try to create file in specific directory but it shows the error FileNotFound. Why?
Am I using impossible path? I really don't know, but is seems like the code should be working.
String day=/1;
String zn="/zn";
File_name=zn
String root= Environment.getExternalStorageDirectory().toString();
File_path=root+day;
File file1 = new File(File_path,File_name);
file1.mkdirs();
if(!file1.exists()) {
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
OutputStream fos= new FileOutputStream(file1);
String l,d,p;
l = lessnum.getText().toString();
d = desc.getText().toString();
p = place.getText().toString();
fos.write(l.getBytes());
fos.write(d.getBytes());
fos.write(p.getBytes());
fos.close();
Change your code as for creating a file on sdcard
String root= Environment.getExternalStorageDirectory().getAbsolutePath();
String File_name = "File_name.Any_file_Extension(like txt,png etc)";
File file1 = new File(root+ File.separator + File_name);
if(!file1.exists()) {
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
In current you you are also missing file Extension with file name so change String zn as zn="/zn.txt";
and make sure you have added Sd card permission in AndroidManifest.xml :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
First you make a directory
String root= Environment.getExternalStorageDirectory().toString();
String dirName =
root+ "abc/123/xy";
File newFile = new File(dirName);
newFile.mkdirs();
then you create a file inside that directory
String testFile = "test.txt";
File file1 = new File(dirName,testFile);
if(!file1.exists()){
try {
file1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
then do your file writing operations
try { OutputStream fos= new FileOutputStream(file1);
String l,d,p;
l = lessnum.getText().toString();
d = desc.getText().toString();
p = place.getText().toString();
os.write(l.getBytes());
fos.write(d.getBytes());
fos.write(p.getBytes());
fos.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I think this will help you...
Thanks...
you will need to give your app the correct permission to write to the SD Card by adding the line below to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And check http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory%28%29
String root= Environment.getExternalStorageDirectory().toString();
String dirName =
root+ "abc/123/xy";
File newFile = new File(dirName);
newFile.mkdirs();
String testFile = "test.txt";
File file1 = new File(dirName,testFile);
if(!file1.exists()){
try {
file1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And and <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
on manifest file...
Thanks...
Here is your latest attempt:
File_path = root + File.separator + day;
File f_dir = new File(File_path);
f_dir.mkdirs();
File file1 = new File(f_dir, File_name);
if (!file1.exists()) {
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
OutputStream fos= new FileOutputStream(file1);
If you showed us the complete stacktrace and error message it would be easier to figure out what is going wrong, but I can think of a couple of possibilities:
You are not checking the value returned by f_dir.mkdirs(), and it could well be returning false to indicate that the directory path was not created. This could mean that:
The directory already existed.
Something existed but it wasn't a directory.
Some part of the directory path could not be created ... for one of a number of possible reasons.
The file1.exists() call will return true if anything exists with that pathname given by the object. The fact that something exists doesn't necessarily mean that you can open it for writing:
It could be a directory.
It could be a file that the application doesn't have write permissions for.
It could be a file on a read-only file system.
And a few other things.
If I was writing this, I'd write it something like this:
File dir = new File(new File(root), day);
if (!dir.exists()) {
if (!dir.mkdirs()) {
System.err.println("Cannot create directories");
return;
}
}
File file1 = new File(dir, fileName);
try (OutputStream fos= new FileOutputStream(file1)) {
...
} catch (FileNotFoundException ex) {
System.err.println("Cannot open file: " + ex.getMessage());
}
I only attempt to create the directory if required ... and check that the creation succeeded.
Then I simply attempt to open the file to write to it. If the file doesn't exist it will be created. If it cannot be created, then the FileNotFoundException message should explain why.
Notice that I've also corrected the style errors you made in your choice of variable names.

How to use Java property files?

I have a list of key/value pairs of configuration values I want to store as Java property files, and later load and iterate through.
Questions:
Do I need to store the file in the same package as the class which will load them, or is there any specific location where it should be placed?
Does the file need to end in any specific extension or is .txt OK?
How can I load the file in the code
And how can I iterate through the values inside?
You can pass an InputStream to the Property, so your file can pretty much be anywhere, and called anything.
Properties properties = new Properties();
try {
properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
...
}
Iterate as:
for(String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
System.out.println(key + " => " + value);
}
You can store the file anywhere you like. If you want to keep it in your jar file, you'll want to use Class.getResourceAsStream() or ClassLoader.getResourceAsStream() to access it. If it's on the file system it's slightly easier.
Any extension is fine, although .properties is more common in my experience
Load the file using Properties.load, passing in an InputStream or a StreamReader if you're using Java 6. (If you are using Java 6, I'd probably use UTF-8 and a Reader instead of the default ISO-8859-1 encoding for a stream.)
Iterate through it as you'd iterate through a normal Hashtable (which Properties derives from), e.g. using keySet(). Alternatively, you can use the enumeration returned by propertyNames().
If you put the properties file in the same package as class Foo, you can easily load it with
new Properties().load(Foo.class.getResourceAsStream("file.properties"))
Given that Properties extends Hashtable you can iterate over the values in the same manner as you would in a Hashtable.
If you use the *.properties extension you can get editor support, e.g. Eclipse has a properties file editor.
There are many ways to create and read properties files:
Store the file in the same package.
Recommend .properties extension however you can choose your own.
Use theses classes located at java.util package => Properties, ListResourceBundle, ResourceBundle classes.
To read properties, use iterator or enumerator or direct methods of Properties or java.lang.System class.
ResourceBundle class:
ResourceBundle rb = ResourceBundle.getBundle("prop"); // prop.properties
System.out.println(rb.getString("key"));
Properties class:
Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
This load the properties file:
Properties prop = new Properties();
InputStream stream = ...; //the stream to the file
try {
prop.load(stream);
} finally {
stream.close();
}
I use to put the .properties file in a directory where I have all the configuration files, I do not put it together with the class that accesses it, but there are no restrictions here.
For the name... I use .properties for verbosity sake, I don't think you should name it .properties if you don't want.
Properties has become legacy. Preferences class is preferred to Properties.
A node in a hierarchical collection of preference data. This class allows applications to store and retrieve user and system preference and configuration data. This data is stored persistently in an implementation-dependent backing store. Typical implementations include flat files, OS-specific registries, directory servers and SQL databases. The user of this class needn't be concerned with details of the backing store.
Unlike properties which are String based key-value pairs, The Preferences class has several methods used to get and put primitive data in the Preferences data store. We can use only the following types of data:
String
boolean
double
float
int
long
byte array
To load the the properties file, either you can provide absolute path Or use getResourceAsStream() if the properties file is present in your classpath.
package com.mypack.test;
import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;
public class PreferencesExample {
public static void main(String args[]) throws FileNotFoundException {
Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
// Load file object
File fileObj = new File("d:\\data.xml");
try {
FileInputStream fis = new FileInputStream(fileObj);
ps.importPreferences(fis);
System.out.println("Prefereces:"+ps);
System.out.println("Get property1:"+ps.getInt("property1",10));
} catch (Exception err) {
err.printStackTrace();
}
}
}
xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
<map />
<node name="mypack">
<map />
<node name="test">
<map>
<entry key="property1" value="80" />
<entry key="property2" value="Red" />
</map>
</node>
</node>
</node>
</root>
</preferences>
Have a look at this article on internals of preferences store
Example:
Properties pro = new Properties();
FileInputStream in = new FileInputStream("D:/prop/prop.properties");
pro.load(in);
String temp1[];
String temp2[];
// getting values from property file
String username = pro.getProperty("usernamev3");//key value in prop file
String password = pro.getProperty("passwordv3");//eg. username="zub"
String delimiter = ","; //password="abc"
temp1=username.split(delimiter);
temp2=password.split(delimiter);
In order:
You can store the file pretty much anywhere.
no extension is necessary.
Montecristo has illustrated how to load this. That should work fine.
propertyNames() gives you an enumeration to iterate through.
By default, Java opens it in the working directory of your application (this behavior actually depends on the OS used). To load a file, do:
Properties props = new java.util.Properties();
FileInputStream fis new FileInputStream("myfile.txt");
props.load(fis)
As such, any file extension can be used for property file. Additionally, the file can also be stored anywhere, as long as you can use a FileInputStream.
On a related note if you use a modern framework, the framework may provide additionnal ways of opening a property file. For example, Spring provide a ClassPathResource to load a property file using a package name from inside a JAR file.
As for iterating through the properties, once the properties are loaded they are stored in the java.util.Properties object, which offer the propertyNames() method.
Reading a properties file and loading its contents to Properties
String filename = "sample.properties";
Properties properties = new Properties();
input = this.getClass().getClassLoader().getResourceAsStream(filename);
properties.load(input);
The following is the efficient way to iterate over a Properties
for (Entry<Object, Object> entry : properties.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
In Java 8 to get all your properties
public static Map<String, String> readPropertiesFile(String location) throws Exception {
Map<String, String> properties = new HashMap<>();
Properties props = new Properties();
props.load(new FileInputStream(new File(location)));
props.forEach((key, value) -> {
properties.put(key.toString(), value.toString());
});
return properties;
}
1) It is good to have your property file in classpath but you can place it anywhere in project.
Below is how you load property file from classpath and read all properties.
Properties prop = new Properties();
InputStream input = null;
try {
String filename = "path to property file";
input = getClass().getClassLoader().getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
return;
}
prop.load(input);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = prop.getProperty(key);
System.out.println("Key : " + key + ", Value : " + value);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2) Property files have the extension as .properties
Here is another way to iterate over the properties:
Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) {
String key = (String) eProps.nextElement();
String value = properties.getProperty(key);
System.out.println(key + " => " + value);
}
I have written on this property framework for the last year.
It will provide of multiple ways to load properties, and have them strongly typed as well.
Have a look at http://sourceforge.net/projects/jhpropertiestyp/
JHPropertiesTyped will give the developer strongly typed properties.
Easy to integrate in existing projects.
Handled by a large series for property types.
Gives the ability to one-line initialize properties via property IO implementations.
Gives the developer the ability to create own property types and property io's.
Web demo is also available, screenshots shown above.
Also have a standard implementation for a web front end to manage properties, if you choose to use it.
Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage.
Here ready static class
import java.io.*;
import java.util.Properties;
public class Settings {
public static String Get(String name,String defVal){
File configFile = new File(Variables.SETTINGS_FILE);
try {
FileReader reader = new FileReader(configFile);
Properties props = new Properties();
props.load(reader);
reader.close();
return props.getProperty(name);
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
return defVal;
} catch (IOException ex) {
// I/O error
logger.error(ex);
return defVal;
} catch (Exception ex){
logger.error(ex);
return defVal;
}
}
public static Integer Get(String name,Integer defVal){
File configFile = new File(Variables.SETTINGS_FILE);
try {
FileReader reader = new FileReader(configFile);
Properties props = new Properties();
props.load(reader);
reader.close();
return Integer.valueOf(props.getProperty(name));
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
return defVal;
} catch (IOException ex) {
// I/O error
logger.error(ex);
return defVal;
} catch (Exception ex){
logger.error(ex);
return defVal;
}
}
public static Boolean Get(String name,Boolean defVal){
File configFile = new File(Variables.SETTINGS_FILE);
try {
FileReader reader = new FileReader(configFile);
Properties props = new Properties();
props.load(reader);
reader.close();
return Boolean.valueOf(props.getProperty(name));
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
return defVal;
} catch (IOException ex) {
// I/O error
logger.error(ex);
return defVal;
} catch (Exception ex){
logger.error(ex);
return defVal;
}
}
public static void Set(String name, String value){
File configFile = new File(Variables.SETTINGS_FILE);
try {
Properties props = new Properties();
FileReader reader = new FileReader(configFile);
props.load(reader);
props.setProperty(name, value.toString());
FileWriter writer = new FileWriter(configFile);
props.store(writer, Variables.SETTINGS_COMMENT);
writer.close();
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
} catch (IOException ex) {
// I/O error
logger.error(ex);
} catch (Exception ex){
logger.error(ex);
}
}
public static void Set(String name, Integer value){
File configFile = new File(Variables.SETTINGS_FILE);
try {
Properties props = new Properties();
FileReader reader = new FileReader(configFile);
props.load(reader);
props.setProperty(name, value.toString());
FileWriter writer = new FileWriter(configFile);
props.store(writer,Variables.SETTINGS_COMMENT);
writer.close();
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
} catch (IOException ex) {
// I/O error
logger.error(ex);
} catch (Exception ex){
logger.error(ex);
}
}
public static void Set(String name, Boolean value){
File configFile = new File(Variables.SETTINGS_FILE);
try {
Properties props = new Properties();
FileReader reader = new FileReader(configFile);
props.load(reader);
props.setProperty(name, value.toString());
FileWriter writer = new FileWriter(configFile);
props.store(writer,Variables.SETTINGS_COMMENT);
writer.close();
} catch (FileNotFoundException ex) {
// file does not exist
logger.error(ex);
} catch (IOException ex) {
// I/O error
logger.error(ex);
} catch (Exception ex){
logger.error(ex);
}
}
}
Here sample:
Settings.Set("valueName1","value");
String val1=Settings.Get("valueName1","value");
Settings.Set("valueName2",true);
Boolean val2=Settings.Get("valueName2",true);
Settings.Set("valueName3",100);
Integer val3=Settings.Get("valueName3",100);
You can load the property file suing the following way:
InputStream is = new Test().getClass().getClassLoader().getResourceAsStream("app.properties");
Properties props = new Properties();
props.load(is);
And then you can iterate over the map using a lambda expression like:
props.stringPropertyNames().forEach(key -> {
System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
});
in my opinion other ways are deprecated when we can do it very simple as below:
#PropertySource("classpath:application.properties")
public class SomeClass{
#Autowired
private Environment env;
public void readProperty() {
env.getProperty("language");
}
}
it is so simple but i think that's the best way!!
Enjoy

Categories