Get up to 80 % extra points for free! More info:

Lesson 18 - Java - Writing/reading data types to/from Windows registry

Quite often there's an issue on ICT.social and other forums with certain settings we made in a program earlier and now we started the program again and we want it to remember these. There are, of course, several ways to do it. We can save these settings to a file via character or byte streams (e.g. *.txt, *.bin, and other file types) or via parsers to configuration *.xml files, or Java allows us to keep the data in Windows registry. And since Java is cross-platform, it should also support this feature on other OSs. No framework is needed to use Windows registry, the technique is part of the Java SE 4 and higher APIs.

In Windows, it's the registry we access with the regedit.exe command. The Java API allows us to write to two registry keys. A key is the Preferences object, which is in the Java API. The technology also has its own documentation and usage description found in Oracle Documents

  • HKEY_CURRENT_USER - The key is located in HKEY_CURRENT_USER\SOFTWARE JavaSoft\Prefs\
  • HKEY_LOCAL_MAC­HINE - The key is located in HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs\

We won't discuss how the registry works here and neither its rules (e.g. different users, access rights, etc.). And not to be "racist", this programming technique can also be successfully used on alternative operating systems, according to stackoverflow. However, I haven't tried saving to the registry on Linux, Unix, Solaris, and MacOS.

On Unix / Linux, the storing path for SystemRoot is /etc/.java and for UserRoot ${user.home}/.java/.userPrefs. For MacOS, the saved data should be located in /Users/"User"/Library/Preferences/.

We can access SystemRoot (HKEY_LOCAL_MAC­HINE) like this:

Preferences.systemRoot()

And we access UserRoot (HKEY_CURRENT_U­SER) like this:

Preferences.userRoot()

Example - creating a node

We'll demonstrate how to work with the Preferences object. In this first example, we'll create a new node in the registry in the HKEY_CURRENT_USER region. If the node already exists, it won't be created and initializing the Preferences object will connect us to the registry level defined in our program.

import java.util.prefs.Preferences;
public class CreateNode {
    @SuppressWarnings("unused")
    private static Preferences prefs;
    public static void main(String[] args) {
        System.out.println("Program started");
        //  create node
        prefs = Preferences.userRoot().node("IctSocialNode");
        System.out.println("Program ended");
    }
}

Open the registry and see that a new node named IctSocialNode has been created in the registry path HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\/Ict/Social/Node.

Files and I/O in Java

Saving data to keys

The Preferences object only allows to store several data types (e.g. String, boolean, byte array, ..). In this example, we'll show how to store these values to the registry easily. Each data type has its own method in the API, the first parameter is the key identifier and the second parameter is the value.

import java.util.prefs.Preferences;

public class StoringData {

    private static Preferences prefs;

    public static void main(String[] args) {
        System.out.println("Program started");
        //  create/connect to the node
        prefs = Preferences.userRoot().node("Example2");
        //  store data
        String string = "Stores String to the registry";
        prefs.put("stringKey", string);
        prefs.putBoolean("booleanKey", true);
        prefs.putDouble("doubleKey", 3.5646d);
        prefs.putFloat("floatKey", 45646.234654f);
        prefs.putInt("intKey", 215646);
        prefs.putLong("longKey", 1846546465);
        System.out.println("Program ended");
    }
}

The example is saved to the HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\/Example2 node. A total of 6 keys are created.

Files and I/O in Java

Reading from keys

We have shown how to store data to the registry, so as you probably expect, we're now going to get the data from the registry back to our program again. The Preferences object has methods that retrieve various data types. The return type of these methods is the data type (information retrieved) from the registers. The first parameter is the name of the key and the second parameter is the value of the data type if the key doesn't exist (see retrieving the "ssKey", which doesn't exist in the registry). Therefore, if the key doesn't exist in the given node, the second parameter is what the method will return.

import java.util.prefs.Preferences;

public class RetrievingData {

    private static Preferences prefs;

    public static void main(String[] args) {
        System.out.println("Program started");
        //  create node
        prefs = Preferences.userRoot().node("Example2");
        //  retrieve data from the registry
        String string = null;
        string = prefs.get("stringKey", string);
        System.out.println("The String value: " + string);

        System.out.println("The Double value: " + prefs.getDouble("doubleKey", 0d));
        System.out.println("The Float value: " + prefs.getFloat("floatKey", 0f));
        System.out.println("The Int value: " + prefs.getInt("intKey", 0));
        System.out.println("The Long value: " + prefs.getLong("longKey", 0L));
        System.out.println("The Boolean value: " + prefs.getBoolean("booleanKey", false));

        System.out.println("A String key which doesn't exist : " + prefs.get("ssKey", "No value"));
        System.out.println("Program ended");
    }
}
Files and I/O in Java

Working with nested nodes

In the last chapter, we're going to show how to create a nested node, list keys in the node, and then a few methods that list the path information of the node, the node's parent, and the node information.

import java.util.prefs.*;

public class NodeHierarchy {

    private static Preferences prefs;
    @SuppressWarnings("static-access")

    public static void main(String[] args) throws BackingStoreException {
        System.out.println("Program started");
        prefs = Preferences.userRoot().node("Program2");
        System.out.println("Node name : " + prefs.absolutePath());
        System.out.println("Parent node : " + prefs.parent());
        System.out.println("Node info : " + prefs.systemRoot());
        prefs = null;
        prefs = Preferences.userRoot().node("Node1").node("Node2").node("Node3");
        System.out.println("Node name : " + prefs.absolutePath());
        System.out.println("Parent node : " + prefs.parent());
        System.out.println("Node info: " + prefs.systemRoot());
        // write keys and values
        prefs.put("Key1", "Value1");
        prefs.put("Key2", "Value2");
        // print keys
        String[] klice = prefs.keys();
        for (String s : klice) {
            System.out.println("Key : " + s);
        }
        System.out.println("Program end");
    }
}
Files and I/O in Java

As you can see, the Java API allows us to store and retrieve registry data. At the same time it allows to work with nested nodes as well.


 

Download

By downloading the following file, you agree to the license terms

Downloaded 587x (9.7 kB)

 

Previous article
Working with custom files in Java - Saving and loading ZIPs
All articles in this section
Files and I/O in Java
Article has been written for you by Robert Michalovic
Avatar
User rating:
No one has rated this quite yet, be the first one!
Activities