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_MACHINE - 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_MACHINE) like this:
Preferences.systemRoot()
And we access UserRoot (HKEY_CURRENT_USER) 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
.
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.
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"); } }
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"); } }
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 termsDownloaded 587x (9.7 kB)