I am working on a program for launching programs, and am using JFileChooser to let the user select the file, i would like the program to have the path of the last file available the next time the user starts my program, what would be the best way to accomplish this?
Use a properties file which acts similarly to a hashtable. This code should be pretty accurate (needs exception handling).
private void save(String _url){
Properties prop = new Properties();
prop.setProperty("url", _url);
prop.store(new FileOutputStream("file.properties"), null);
}
private String open(){
Properties prop = new Properties();
prop.load(new FileInputStream("file.properties"));
return prop.getProperty("url");
}
Either your program is web based then stored it in session, or write in file.
Related
This question already has answers here:
Where to place and how to read configuration resource files in servlet based application?
(6 answers)
Closed 3 years ago.
I am working on a webapp using Maven and Java servlets. I'm trying to build a connection to my local Postgres Database by retrieving its credentials from a Properties file because I don't want to hard code them. For this im using FileInputStream in a "getProperties" general method. The problem is that i am using a Tomcat Server, so the project runs from the Tomcat directory, and I'm having trouble setting it so that my fellow programmers can run my app on their own machines without having to hardcode a directory. The final goal is to only have to change the file itself and never the code.
So i have a Properties file like this:
port = localhost
bdname = clothingdb
user = jmbs
pw = 123
and im trying to retrieve them like this:
String port = getProperties("port");
String bdname = getProperties("bdname");
String user = getProperties("user");
String pw = getProperties("pw");
Using this method:
public String getProperties(String propriedade)
{
String parametro = null;
try (InputStream input = new FileInputStream("svlocal.properties")) {
Properties prop = new Properties();
// load a properties file
prop.load(input);
// get the property value and print it out
parametro = prop.getProperty(propriedade);
} catch (IOException ex) {
ex.printStackTrace();
}
return parametro;
}
For this i get the "File not found" error, because the project runs from the tomcat/bin directory and not from the
NetBeansProjects/bookstore/ directory where i need to have the Properties file.
My actual question is, how can i set the Properties file, so that when i send my project to someone else he only has to run it and change the credentials on the Properties file to access his own local database, and not having to change directories or hard code them on the
getProperties() method? Thanks in advance.
You can add the file in classpath and then load it as below,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("src/main/resources/svlocal.properties")
Ok, so, i was able to solve the problem using javaadict's suggestion but with a twist. I created a new directory in src/main/resources and added the properties file to it. then i used the following method:
public String getProperties(String propriedade){
String parametro = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try (InputStream input = classLoader.getResourceAsStream("svlocal.properties")) {
Properties prop = new Properties();
// load a properties file
prop.load(input);
// get the property value and print it out
parametro = prop.getProperty(propriedade);
} catch (IOException ex) {
ex.printStackTrace();
}
return parametro;
}
It seems that because im using maven it recognizes the resources folder in src/main/resources and i was able to load the file just by using "svlocal.properties" in the getResourceAsSteam method.
Ty for the valuable suggestion javaaddict.
I have something like this as Code, and it works fine but how
but i want replace the absolute path with System.getProperty("user.dir");
but this gives me back a string with backslahses how can i resolve it,
or replace this so that converts this to c:/........
public static void main(String[] args) throws Exception{
String strPropertiePath=System.getProperty("user.dir");
System.out.println("strPropertiePath "+strPropertiePath);
String absoluthPath2Propertie = "C:/Users/maurice/Dropbox/a_projectturkey/solution_06_09_2014/Application_Propertie/logging.properties";
File fileLog = new File(absoluthPath2Propertie);
LogManager.getLogManager().readConfiguration(new FileInputStream(absoluthPath2Propertie));
//ConfigSystem.setup();
}
}
Just use File or Path objects with proper parent-child relations. You do not need to care about slashes and blackslashes, File and Path will take care about them for you.
E.g. to define a property file which sits in the user dir folder in a subfolder of props and having a file name myprops.properties, you can use it like this:
File propFile = new File(System.getProperty("user.dir"),
"/props/myprops.properties");
And you can load this property file like this:
// Use try-with-resources to properly close the file input stream
try (InputStream in = new FileInputStream(propFile)) {
LogManager.getLogManager().readConfiguration(in);
}
Edit:
So if you need a file named logging.properties in your user dir, simply use this:
File propFile = new File(System.getProperty("user.dir"),
"logging.properties");
try (InputStream in = new FileInputStream(propFile)) {
LogManager.getLogManager().readConfiguration(in);
}
Use the following code to load the property file.
Properties properties=new Properties();
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
properties.load(in);
properties.get("user.dir");
You can get the system filesystem path delimiter with the following piece of code:
System.getProperties("file.separator")
By using this you will be able to create a correct path on any supported platform. Such that you can use slashes in UNIX/Linux based systems and backslashes on Windows.
I have a real quick question. I have a Java program in which I use a properties file. The file is used for keeping track of the program's users. My problem is I cannot figure out how to ADD to the file. I know how to set existing properties to a value, but I don't know how to add more properties without over writing the other ones.
I would like the program to 'register' users, so to speak. Whenever a new users 'signs up', I want the program to add a new property containing the new user's information. I run into this problem though:
Example:
File: numOfUsers=0
One user registers. The username is 'c00lGuy'. The program registers this in the file:
File: numOfUsers=1 user1-username=c00lGuy
Another user registers. She decides to call her username 'theGr8Girl'. The program registers this:
File: numOfUsers=2 user2-username=theGr8Girl
The file after the two users registered:
File: numOfUsers=2 user2-username=theGr8Girl
How do I prevent my program from overwriting existing lines in the file? It seems to erase the file's contents, and then add what I tell it to. I don't want it to erase the file's contents.
The code I am using to register the properties:
Properties prop = new Properties();
OutputStream output = null;
int userCount = getUserCount();
userCount++;
try {
output = new FileOutputStream(fileName);
// set the properties value
prop.setProperty("numOfUsers", String.valueOf(userCount));
prop.setProperty("user" + userCount + "-username", username);
// save properties to project root folder
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null)
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Try something like this:
FileOutputStream out = new FileOutputStream(fileName);
props.setProperty("numOfUsers", 2);
...
props.store(out, null);
out.close();
Properties files aren't really intended for this sort of usage, but if you have a small enough data set it'll work.
The step you are missing is that you need to read the properties from disk, make the changes, then save them back to disk.
Properties props = new Properties();
try{
props.load(inputStream);
} finally {
inputStream.close();
}
props.setProperty(....);
try{
props.store(outputStream);
} finally {
outputStream.close();
}
Just bear in mind that this is not at all suitable for any sort of volume processing. Also, there is a race condition if you have two threads trying to make changes to the properties file at the same time.
If you are looking for a lightweight persistent store, I highly recommend mapdb.
You code is creating a new Properties object each time. Make sure to reuse the old instance when adding a user.
The typical format for a line in this file would be
user=hashedPassword
so use the username as the key and the password as a value. The number of users does not need to be stored, it is just the size of the properties map.
I want to take place database.properties outside the project, so when I want to change the content (database configuration) of that when I've build them into jar, I can do it easily without open my project again. So what to do?
First, place the database.properties file in the location you'd like it to be in.
Then, do one of the following:
Add the directory where database.properties is located, to the classpath. Then use Thread.currentThread().getContextClassLoader().getResource() to get a URL to the file, or getResourceAsStream() to get an input stream for the file.
If you don't mind your Java application knowing the exact location of the database.properties file, you can use simple File I/O to obtain a reference to the file (use new File(filename)).
Usually, you'd want to stick with the first option. Place the file anywhere, and add the directory to the classpath. That way, your Java application doesn't have to be aware of the exact location of the file - it will find it as long as the file's directory is added to the runtime classpath.
Example (for the first approach):
public static void main(String []args) throws Exception {
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties");
Properties props = new Properties();
try {
// Read the properties.
props.load(stream);
} finally {
// Don't forget to close the stream, whatever happens.
stream.close();
}
// When reaching this point, 'props' has your database properties.
}
Store properties file in your preferred location. Then do the following:
try {
String myPropertiesFilePath = "D:\\configuration.properties"; // path to your properties file
File myPropFile = new File(myPropertiesFilePath); // open the file
Properties theConfiguration = new Properties();
theConfiguration.load(new FileInputStream(myPropFile)); // load the properties
catch (Exception e) {
}
Now you can easily get properties as String from the file:
String datasourceContext = theConfiguration.getString("demo.datasource.context", "jdbc/demo-DS"); // second one is the default value, in case there is no property defined in the file
Your configuration.properties file might look something like this:
demo.datasource.context=jdbc/demo-DS
demo.datasource.password=123
i am writing standalone java app for production monitoring. once it starts running the api is configured for default values which is set in .properties file. in running state the api's configuration can be changed and the .properties file should be updated accordingly. is there a way to achieve this ? or are there any other approaches to implement this ?
Thanks in advance
The Java Properties class (api here) specifies "load" and "store" methods which should do exactly that. Use FileInputStream and FileOutputStream to specify the file to save it into.
You could use a very simple approach based on the java.util.Properties class which has indeed a load and store methods that you can use in conjunction with a FileInputStream and FileOutputStream:
But actually, I'd recommend to use an existing configuration library like Commons Configuration (amongst others). Check the Properties Howto to see how to load, save and automatically reload a properties file using its API.
I completely agree that Apache Commons Configuration API is really good choice.
This example update properties at runtime
File propertiesFile = new File(getClass().getClassLoader().getResource(fileName).getFile());
PropertiesConfiguration config = new PropertiesConfiguration(propertiesFile);
config.setProperty("hibernate.show_sql", "true");
config.save();
From the post how to update properties file in Java
Hope this help!
java.util.Properties doesn't provide runtime reloading out-of-the-box as far as I know.
Commons Configuration provides support for reloading configuration at runtime. The reload strategy can be configured by setting a ReloadingStrategy on the PropertiesConfiguration object. It also offers various other useful utilities for making your application configurable.
In addition to the load and store method of the Properties class, you can also use the Apache Commons Configuration library, which provides functions to easily manipulate configuration files (and not only .properties files).
Apache common configuration API provided different strategies to reload property files at run time. FileChangedReloadingStrategy is one of them. Refer this link to see an example for property file reloading at run time using FileChangedReloadingStrategy.
Try this:
// Write in property file at runtime
public void setValue(String key, String value) {
Properties props = new Properties();
String path = directoryPath+ "/src/test/resources/runTime.properties";
File f = new File(path);
try {
final FileInputStream configStream = new FileInputStream(f);
props.load(configStream);
configStream.close();
props.setProperty(key, value);
final FileOutputStream output = new FileOutputStream(f);
props.store(output, "");
output.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
// Read same file
public String getValue(String key) {
String value = null;
try {
Properties prop = new Properties();
File f = new File(directoryPath+"/src/test/resources/runTime.properties");
if (f.exists()) {
prop.load(new FileInputStream(f));
value = prop.getProperty(key);
}
} catch (Exception e) {
System.out.println("Failed to read from runTime.properties");
}
return value;
}