So if we do like this:
Properties props = new Properties();
OutputStream osr = new FileOutputStream(Store.class.getResource("my.properties").getFile());
props.setProperty("wallboard_text_rgb", "aaa");
props.setProperty("wallboard_back_rgb", "bbb");
props.store(osr, "");
other keys in existing properties will be deleted, how to avoid that?
Load properties from that file before modifying it. In other words, replace
Properties props = new Properties();
with
Properties props = Properties.load(new FileInputStream(Store.class.getResource("my.properties").getFile()));
The simplest solution is to use
String filename = Store.class.getResource("my.properties").getFile();
OutputStream osr = new FileOutputStream(filename, true); // append.
If you don't want to keep appending to the file, you have to read all the existing values and re-write them. Unfortunately properties don't preserve order, or comments, blanks lines etc.
Related
Currently, my property file output looks like this
Name=Frank
Email=frank#mail.com
based on the following codes
File prop = new File(".properties");
if (!prop.exists()) {
prop.createNewFile();
}
try {
FileReader reader = new FileReader(prop);
Properties properties = new Properties();
properties.load(reader);
reader.close();
properties.setProperty("Name", name);
properties.setProperty("Email", email);
FileWriter writer = new FileWriter(prop);
properties.store(writer, "Settings");
writer.close();
} catch (IOException ex) {
Logger.getLogger(PropertiesTest.class.getName()).log(Level.SEVERE, null, ex);
}
I want it to be written in one line, with each key value pair separated by a comma. So it will look like this
Name=Frank, Email=frank#mail.com
How can I achieve this? Or is there a way to group each Name and Email key value pairs with a unique identifier?
Basically, I want to have multiple Name and Email entries in one property file and to be able to get each of the entry.
The properties file is not designed to do this. You should instead use CSV, JSON, YAML, XML (but probably XML is too complicated for this use case) or a database.
I have an application that implements a JTree and populates the tree with a java properties file as default; The nodes are the keys and the values are the contents of the node. The application was designed to be dynamic so a JButton and JTextField are implemented to take in new values and put the values in the exists keys in the properties file.
So for example I have the line below as a default value in a sample.properties file
node=cat,dog,mice
and using the JTextField and JButton I input "rabbit" to append to the node, to look like:
node=cat,dog,mice,rabbit
I've implemented JTextField and JButton and have them working but I just can't seem to find a good way to append new values to existing keys in the properties file.
Just FileWriter
FileWriter fileWritter = new FileWriter("example.properties", true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.append("PROPERTES_YOUR_KEY=PROPERTES_YOUR_VALUE");
bufferWritter.close();
Update
Properties API does not support, I am not sure why you need this functionality.
You can try as below :
example.properties
PROPERTIES_KEY_3=PROPERTIES_VALUE_3
PROPERTIES_KEY_2=PROPERTIES_VALUE_2
PROPERTIES_KEY_1=PROPERTIES_VALUE_1
Program
Properties pop = new Properties();
pop.load(new FileInputStream("example.properties"));
pop.put("PROPERTIES_KEY_3", "OVERWRITE_VALUE");
FileOutputStream output = new FileOutputStream("example.properties");
pop.store(output, "This is overwrite file");
output
PROPERTIES_KEY_3=OVERWRITE_VALUE
PROPERTIES_KEY_2=PROPERTIES_VALUE_2
PROPERTIES_KEY_1=PROPERTIES_VALUE_1
I would look at Apache Commons Configuration.
It has very specific examples that do what you are asking.
Try:
import org.apache.commons.configuration.PropertiesConfiguration;
PropertiesConfiguration config = new PropertiesConfiguration(
"config.properties");
config.setProperty("my.property", somevalue);
config.save();
Let's say that I have a TreeMap and I want to take all values for a key, make a file with these, pass the file to another process loop and do this for every map key, so I always have to use the same file but its content must be replaced every time for each key.
What I do is:
PrintWriter writeRatings = new PrintWriter("ratings.txt", "UTF-8");
TreeMap<Integer, ArrayList<Rating>> ratings = new TreeMap<Integer, ArrayList<Rating>>();
-->
for(Integer clID:ratings.keySet()){
ArrayList<Rating> ratingGroup = ratings.get(clID);
for(Rating r:ratingGroup){
witer.println(r.toString());
}
}
writer.flush();
writer.close();
With this, I get a file with all the data for each map key. Can you suggest how can I get only the data from the current key each time in the file?
If you want to use the same file and just append lines to it, use a FileWriter and set the append mode to true
PrintWriter writer = new PrintWriter(new FileWriter("filename", true));
This will append lines to the file, instead of over writing the file. This way, different processes can use the same file and keep on adding new data to the file
So what worked for me was to include this line into the for loop in the position of the arrow in the main question post:
PrintWriter writer = new PrintWriter(new FileWriter("filename"));
I am trying to modify a config file in Java using Properties. I try to modify two of the multiple entries like this:
Properties properties = new Properties();
FileInputStream fin = null;
FileOutputStream fout = null;
fin = new FileInputStream(mCallback.getConfFile());
fout = new FileOutputStream(mCallback.getConfFile());
properties.load(fin);
properties.setProperty(Wrapper.GAME_PATH_KEY, (String)gamePathText.getText());
properties.setProperty(Wrapper.GAME_TYPE_KEY, (String)selectedGame.getSelectedItem());
properties.store(fout, null);
But when I check the file after the result I find out that the whole file was overwritten, leaving only these two entries. This is an android app though I guess it's not relevant to the problem here. What I am doing wrong?
You have to read all properties and then modify the ones you want. After that you have to write all to file. You cannot do only an item modification. The Properties API doesn't provide that functionality to modify.
Edit:
Interchange these two statements-
fout = new FileOutputStream(mCallback.getConfFile());
properties.load(fin);
You should load first before you create a file with the same name.
From Properties:
public void store(OutputStream out,
String comments)
throws IOException
Writes this property list (key and element pairs) in this Properties table to the output > stream in a
format suitable for loading into a Properties table using the
load(InputStream) method.
Properties from the defaults table of this
Properties table (if any) are not written out by this method.
This method outputs the comments, properties keys and values in the
same format as specified in store(Writer), with the following
differences:
So, Load the data first, then set the required data, then store it.
Properties prop =new Properties();
prop.load(new FileInputStream(filename));
prop.setProperty(key, value);
prop.store(new FileOutputStream(filename),null);
The previous poster was kind of right, just not at the right place.
You need to open the FileOutputStream after you've loaded the properties otherwise it clears the file's content.
Properties properties = new Properties();
FileInputStream fin = null;
FileOutputStream fout = null;
fin = new FileInputStream(mCallback.getConfFile());
// if fout was here, the file would be cleared and reading from it would produce no properties
properties.load(fin);
properties.setProperty(Wrapper.GAME_PATH_KEY, (String)gamePathText.getText());
properties.setProperty(Wrapper.GAME_TYPE_KEY, (String)selectedGame.getSelectedItem());
fout = new FileOutputStream(mCallback.getConfFile());
properties.store(fout, null);
I have a single UTF-8 encoded String that is a chain of key + value pairs that is required to be loaded into a Properties object. I noticed I was getting garbled characters with my intial implementation and after a bit of googling I found this Question which indicated what my problem was - basically that Properties is by default using ISO-8859-1. This implementation looked like
public Properties load(String propertiesString) {
Properties properties = new Properties();
try {
properties.load(new ByteArrayInputStream(propertiesString.getBytes()));
} catch (IOException e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return properties;
}
No encoding specified, hence my problem. To my question, I can't figure out how to chain / create a Reader / InputStream combination to pass to Properties.load() that uses the provided propertiesString and specifies the encoding. I think this is mostly due to my inexperience in I/O streams and the seemingly vast library of IO utilities in the java.io package.
Any advice appreciated.
Use a Reader when working with strings. InputStreams are really meant for binary data.
public Properties load(String propertiesString) {
Properties properties = new Properties();
properties.load(new StringReader(propertiesString));
return properties;
}
private Properties getProperties() throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("your file");
InputStreamReader inputStreamReader = new InputStreamReader(input, "UTF-8");
Properties properties = new Properties();
properties.load(inputStreamReader);
return properties;
}
then usage
System.out.println(getProperties().getProperty("key"))
Try this:
ByteArrayInputStream bais = new ByteArrayInputStream(propertiesString.getBytes("UTF-8"));
properties.load(bais);