13

I'm using java.util.prefs.Preferences for application preferences. And I need ability to edit those preferences manually. Is it possible to store it into file instead of Windows Registry? Or I should use another mechanism instead of java.util.prefs.Preferences?

denys
  • 2,437
  • 6
  • 31
  • 55
  • [java.util.Properties](http://download.oracle.com/javase/tutorial/essential/environment/properties.html) maybe? It's less fine grained than Preferences though. – BalusC Apr 19 '12 at 13:18
  • I guess you haven't resorted to the [Javadoc](http://docs.oracle.com/javase/1.4.2/docs/api/java/util/prefs/Preferences.html) yet. Do it and see if you still have anything to ask. – Marko Topolnik Apr 19 '12 at 13:21
  • 2
    @MarkoTopolnik you meant "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.**" ??? – denys Apr 19 '12 at 13:36
  • 2
    The Javadoc link is now a 404. (Yay Oracle?) The updated link is [here](http://docs.oracle.com/javase/7/docs/api/java/util/prefs/Preferences.html) – KathyA. Sep 03 '14 at 23:55
  • possible duplicate of [Is there a way to use java.util.Preferences under Windows without it using the Registry as the backend?](http://stackoverflow.com/questions/208231/is-there-a-way-to-use-java-util-preferences-under-windows-without-it-using-the-r) – Erwin Bolwidt Sep 22 '14 at 04:31

7 Answers7

10

If you want to continue using the Preferences API, but write to a file, you will need a new PreferencesFactory, as detailed in this SO post.

Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
8

You are going to want to use the following two method :

 Preferences.exportSubtree(OutputStream os) 

and

Preferences.importPreferences(InputStream is)
Colin D
  • 5,641
  • 1
  • 23
  • 35
  • In case it's useful to others, if using this in Android, exportSubtree() fails on Samsung devices (tested on Lollipop), whereas exportNode() works on all phones. Of course, if you want to save all the descendants of the nodes, then exportNode() will not work. – Rajath Mar 21 '18 at 00:46
4

This code should help you [http://java.sun.com/developer/technicalArticles/releases/preferences/]:

public class PrefSave {

private static final String PACKAGE = "/pl/test";

public static void main(String[] args) {
    doThings(Preferences.systemRoot().node(PACKAGE));
    doThings(Preferences.userRoot().node(PACKAGE));
}

public static void doThings(Preferences prefs) {
    prefs.putBoolean("Key0", false);
    prefs.put("Key1", "Value1");
    prefs.putInt("Key2", 2);

    Preferences grandparentPrefs = prefs.parent().parent();
    grandparentPrefs.putDouble("ParentKey0", Math.E);
    grandparentPrefs.putFloat("ParentKey1", (float) Math.PI);
    grandparentPrefs.putLong("ParentKey2", Long.MAX_VALUE);

    String fileNamePrefix = "System";
    if (prefs.isUserNode()) {
        fileNamePrefix = "User";
    }
    try {
        OutputStream osTree = new BufferedOutputStream(
                new FileOutputStream(fileNamePrefix + "Tree.xml"));
        grandparentPrefs.exportSubtree(osTree);
        osTree.close();

        OutputStream osNode = new BufferedOutputStream(
                new FileOutputStream(fileNamePrefix + "Node.xml"));
        grandparentPrefs.exportNode(osNode);
        osNode.close();
    } catch (IOException ioEx) {
        // ignore
    } catch (BackingStoreException bsEx) {
        // ignore too
    }
}
Piotr Kochański
  • 21,862
  • 7
  • 70
  • 77
2

Try the following class which allows you to use some simple put() and get() functions using a local configuration.xml file.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;

public class SimpleProperties
{
    private String propertiesFilePath;
    private Properties properties;

    public SimpleProperties() throws InvalidPropertiesFormatException, IOException
    {
        propertiesFilePath = "configuration.xml";
        properties = new Properties();

        try
        {
            properties.loadFromXML(new FileInputStream(propertiesFilePath));
        } catch (InvalidPropertiesFormatException e)
        {

        }
    }

    public void put(String key, String value) throws FileNotFoundException, IOException
    {
        properties.setProperty(key, value);

        store();
    }

    public String get(String key)
    {
        return properties.getProperty(key);
    }

    private void store() throws FileNotFoundException, IOException
    {
        String commentText = "Program parameters";

        properties.storeToXML(new FileOutputStream(propertiesFilePath), commentText);
    }
}
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
0

It is explained in another post, here

Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("foo.properties");
prop.load(in);
in.close()
Community
  • 1
  • 1
Ekrem KENTER
  • 316
  • 2
  • 11
  • sorry - it is not the same. [Comparing Preferences API to Other Mechanisms](http://docs.oracle.com/javase/1.5.0/docs/guide/preferences/index.html#prefs-other). In windows there are two places where preferences could be placed. Registry or %APPDATA%. F.e. in QSettings (Qt Framework) I could select between those 2 options... – denys Apr 19 '12 at 13:32
  • 2
    Sorry, I have misunderstood. What about that? I could not test but it seems what you are looking for. http://www.davidc.net/programming/java/java-preferences-using-file-backing-store – Ekrem KENTER Apr 19 '12 at 13:42
  • Much better. Thank you, @MEK. – denys Apr 19 '12 at 13:44
0

I think you can use property files instead. They are stored in the file system. You can define the path you want. And you can edit it by hand. See this question for more details.

Community
  • 1
  • 1
bubblez
  • 814
  • 1
  • 8
  • 14
0

A while back I had to come up with an implementation of the Preferences class that would read settings from but not write to the registry. I derived a ReadOnlyPreferences class from AbstractPreferences to accomplish this. Later, I needed this exact same functionality you require to go to/from files. I just extended my ReadOnlyPreferences class to override sync() and flush() to keep the file in sync. The cool part about this it would use the exact same logic to apply defaults to the values just like the usual use of the prefs since nothing actually existed in the registry to read. I kept the file in sync by using exportSubtree() and importPreferences() from the base class to do all the heavy lifting for me.

I am sorry I cannot post the code as I don't own it but I used the encrypted preferences stuff you can find at the following link as a start point. That's what I did and it took me about an hour to distill it down to just what I needed which was mainly throwing code away which is much easier than writing code! It is also published in Dr Dobbs at the following link if you don't want to click on the first one. I just never saw an easy place on the dobbs article to download the entire source. Regardless, the article is the best I've seen for extending the preferences stuff.

http://www.panix.com/~mito/articles/#ep

http://www.drdobbs.com/security/encrypted-preferences-in-java/184416587?pgno=4

mccorb
  • 41
  • 2