Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Property Files problem 1

Status
Not open for further replies.

SSJ

Programmer
Sep 26, 2002
54
PT
I'm trying to use Property files in java, using java.util.Properties class.

I can load them ok from the file I want and work around with them using getProperty, setProperty methods. The problem arises when I'm trying to write them to disk.

This example, my property file:

# Important Comment1
key1=A
#Important Comment2
key2=B

And my code to change the value of key1 into "C":

properties.load(new java.io.FileInputStream(propertyFilePath));
propFile.setProperty("key1","C");
properties.store(new FileOutputStream(propertyFilePath), null);

I think this is the way of doing it, and it works, but there are 2 things that happen and I'd like to know if I can avoid them:

1-All the comments on my original properties file are erased
2-The order of the keys in the new property file isn't the same as in the original one (ie for example key2 would appear b4 key1 in the file, in this case maybe not but my original file as more than 10 keys and this happens everytime)

What I'd like to do is to write the new edited property file just like the first one, maintaing their comments and order of keys, just altering the values.
Comments and order are really important here since I can't have sections inside property files like in the .ini files used in VB or C++.

Any help is appreciated

TIA
 
My belief is that you would have to override the default behavior of the load/store functionality. This would likely be a large piece of development.

My suggestion is that if the default behavior of property files does not meet your needs you should move to using XML files. They are much more flexible and powerful.


-pete
 
Pete has a point - XML is alot easier to manipulate.

However, the other root is to basically re-write the Properties class yourself.

Have a look at the below - its not the best code in the world, but I it will do the job you wish ..

Ben

Code:
import java.io.*;
import java.util.*;

public class Properties2 {
	File file = null;
	Hashtable hash = null;


	public void load(String filename) throws IOException {
		load(new File(filename));
	}

	public String getProperty(String name) {
		String orig = name;
		for (int i = 0; i < hash.size(); i++) {
			name = i+&quot;|&quot;+name;
			if (hash.containsKey(name)) {
				System.err.println(hash.get(name));
				return (String)hash.get(name);
			} else {
				name = orig;
			}

		}
		return null;

	}

	public boolean setProperty(String name, String value) {
		String orig = name;
		for (int i = 0; i < hash.size(); i++) {
			name = i+&quot;|&quot;+name;
			if (hash.containsKey(name)) {
				hash.remove(name);
				hash.put(name, value);
				return true;
			} else {
				name = orig;
			}
		}
		return false;
	}

	public void save(String fileOutName) throws IOException {
		save(new File(fileOutName));
	}

	public void save(File fileOut) throws IOException {

		Enumeration enum = hash.keys();
		String name = &quot;&quot;;

		ArrayList arr = new ArrayList();
		while (enum.hasMoreElements()) {
			name = (String)enum.nextElement();
			arr.add(name +&quot;=&quot; +hash.get(name));
		}

		PrintWriter pw = new PrintWriter(new FileOutputStream(fileOut));
		for (int i = 0; i < arr.size(); i++) {
			for (int k = 0; k < arr.size(); k++) {
				StringTokenizer st = new StringTokenizer((String)arr.get(k), &quot;|&quot;);
				int thisnum = Integer.parseInt(st.nextToken());
				String name1 = st.nextToken();

				if (thisnum == i) {
					pw.println(name1);
				}
			}
		}

		pw.flush();
		pw.close();
	}

	public void load(File file) throws IOException {
		this.file = file;
		hash = new Hashtable();
		BufferedReader br = new BufferedReader(new FileReader(file));
		String line = &quot;&quot;;
		StringTokenizer st = null;
		String name = null;
		String value = null;
		int commentCnt = 1;
		int lineCnt = 0;
		while ((line = br.readLine()) != null) {
			st = new StringTokenizer(line, &quot;=&quot;);
			// name=value here
			if (st.countTokens() == 2) {
				name = st.nextToken();
				value = st.nextToken();
				hash.put(lineCnt +&quot;|&quot;+name, value);
				lineCnt++;
				//System.err.println(name +&quot; &quot; +value);
			// comment here
			} else if (st.countTokens() == 1) {
				name = &quot;comment&quot; +commentCnt;
				value = st.nextToken();
				hash.put(lineCnt +&quot;|&quot;+name, value);
				//System.err.println(name +&quot; &quot; +value);
				commentCnt++;
				lineCnt++;
			// dunno - exit
			} else {
				System.err.println(&quot;Encountered odd line makeup in file &quot; +file.toString() +&quot; - line is :: &quot; +line);
				System.exit(1);
			}
		}
	}

	public static void main(String args[]) throws IOException {

		Properties2 p = new Properties2();
		p.load(&quot;testIn.properties&quot;);
		p.getProperty(&quot;bbb&quot;);
		p.setProperty(&quot;bbb&quot;, &quot;QQQ&quot;);
		p.getProperty(&quot;bbb&quot;);
		p.save(&quot;testOut.properties&quot;);

	}

}
 
Thanks for the replies!
sedj your code was exactly what I was looking for, I though I could do it through the propertyFile methods.
I only needed to make a few adjustments to the save method of your code and it's now doing what I want. Thanks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top