Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In Windows the default way is registry. This allow you to differentiate system-wide and per-user settings.

In Unix you should use text files in the /etc folder for system-wide settings (what's the convention for per-user settings?).

Many new programs (and especially those designed for being portable) use XML files.

  • What's the best way (and location) to store non-BLOB settings?
  • Should we follow each system default or have a unified solution?
  • And what's the best portable way?
share|improve this question
    
Please be very specific about what you mean with "best". –  user1249 Nov 26 '10 at 16:48
2  
@Thorbjørn: best adj \ˈbest\ superlative of good –  Lorenzo Nov 26 '10 at 18:05
3  
you would be astonished at the diversity of meanings of "best" on StackExchange sites. –  user1249 Nov 26 '10 at 18:12
add comment

11 Answers

up vote 13 down vote accepted

What's the best way (and location) to store non-BLOB settings?

On Windows, it seems acceptable to use the registry. In my opinion, the registry was a poorly-devised system, and instead a simple text file in the Users\Username\AppData directory should be preferred. This is easier to back up, less dangerous for users to modify, and easier to clean up.

On Linux and most Unixes, The preferred location is /home/user/.config/appname for user-specific settings and /etc/ for global (system-wide) settings. The less-preferred (but acceptable) location for user settings is ~/.appname, but this is generally falling out of favor. These files should be user-editable, so a human-readable format is always preferred.

I disagree with most people that XML is an acceptable format for storing non-blob data. It is, in my opinion, an overwrought and excessively complex format for what usually ends up being very small pieces of structured data. I prefer to see files in YAML, JSON, ASN.1, name=value pairs, or similar formats. Having too much syntax makes it too easy for a user to mess up and leave the file in an invalid format.

Should we follow each system default or have a unified solution?

That is entirely up to you, but keep some things in mind:

  • Platforms like *nix have strict limitations on which locations are writable. More strict than Windows. So:
    • The only place you should write to anything is in the user's home directory.
    • Unless your application is a system service; in which case, all mutable data files should be written in /var/. Nonmutable data files should be kept in your app directory in /usr/share/ or /usr/local/share/ or /opt/
    • Configuration files in /etc/ should never be written to by the application when it is running, even if it has write access to them. /etc/ should be the repository for default behaviors and nothing else.
    • Plan for your application to be installed in one of three places: /usr/local/, /opt/appname, or /home/username/appname.
    • Blobs should be stored alongside other configuration files if they are to be changed. It is generally preferable to use a user-editable format, so something like SQLite or Berkeley DB is preferred (since there are command-line tools for each), but not required.
  • On Windows, your applications should only ever write in the User directory. The standardized location for data files is Users\User\AppData. Nowhere else seems acceptable.
  • On Mac OS X, your application settings should be stored in ~/Library/Preferences along with all of the other applications' plist files. plist seems to be the preferred format, but you'll want to double-check with the Apple guidelines.

And what's the best portable way?

There is no "best," to be honest. There are only platform-specific limitations and expectations. My recommendation is to stick with platform-specific means, even if it means writing more code.

share|improve this answer
1  
I think Microsoft has been discouraging the use of the registry for a few years now - which is good. Writing to AppData, as you mentioned, is the way to go. In .NET (maybe also in the Windows API?) there's even a method that returns the correct path. –  MetalMikester Oct 9 '10 at 23:21
    
There's also an environment variable: %APPDATA% –  greyfade Oct 10 '10 at 6:13
    
@MetalMikester - yes, absolutely spot on. AppData is supported by Roaming Profile for a domain environment too. –  JBRWilkinson Oct 10 '10 at 18:58
add comment

Under Windows, use %APPDATA%\appname. Under *NIX, use ~/.appname. Don't use fixed directory names under either platform, since the user's home directory can be different from the default (it could be on the network, for example).

As for the format, use whatever you think is best. That is a decision that only you can make in the context of your application. It is unnecessary, and indeed, inadvisable, to have a "standard" way of doing it, if that "standard" way isn't what's best for your particular program.

For example, XML/JSON might be a good way of storing user data/configuration if your application already uses XML/JSON for something else. But if it's a simple configuration file, why add bloat to your app by introducing a dependency? In that case, it's probably best to just use a simple text file with var: value\n lines instead.

EDIT: There isn't a "best" portable way, since OSes use very different conventions for this. Don't break OS standards without a bloody good reason.

EDIT2: If you find yourself making a system-wide setting in /etc or HKEY_LOCAL_MACHINE, ask yourself if the setting is really global. Then wait 5 minutes and ask yourself again. If the answer is still yes, then by all means, make a global setting. Remember, a normal user doesn't have write access to /etc or HKEY_LOCAL_MACHINE and by doing this, you're ensuring that someone without admin rights can't install your app.

share|improve this answer
    
The first paragraph allows one to use Path.Combine or something similar and thus set the relative root location once to %APPDATA% or ~ and let the code do the rest, for EDIT2 there indeed doesn't exist a cross-platform solution I know of. Maybe there are people that have written a cross-platform configuration library for that purpose, it would at least be a nice idea... –  Tom Wijsman Sep 15 '10 at 16:42
1  
@TomWij: Surely any competent developer should be able to figure out that you don't need to use literals everywhere ;). That's what variables are for. –  Chinmay Kanchi Sep 15 '10 at 16:53
1  
~/.config/applicaton is increasingly becoming the preferred location on *nix. –  greyfade Sep 15 '10 at 16:56
    
@greyfade: I never actually realised this, but you're right. On my machine, about a quarter of the applications that store config data in ~ do so in ~/.config/appname. –  Chinmay Kanchi Sep 15 '10 at 17:18
    
A whole bunch of apps use ~/.appname in Windows (which equates to your user profile dir, NOT documents) and it's so very annoying. Those folders don't hide themselves! –  Alan Pearce Nov 26 '10 at 16:39
add comment

I try and keep out of the registry, it is way over used. I wish everyone would.

I like keeping xml config files or a bin file or occasionally a local database (SQLite).

share|improve this answer
    
+1 for keeping out of the registry. I can't find it now, but I seem to remember reading that someone at MS had admitted that the registry was a mistake. –  Chinmay Kanchi Sep 15 '10 at 16:57
1  
Agree with you except the XML part. I would use ini (or simple text file) for simple setting requirement and SQLite for complex apps. –  Codism Sep 15 '10 at 16:57
    
They're just now admitting that? I coulda told you that back in 1995! Mac OS Classic got it right: A Preferences folder to give you a centralized place to store config info, with each app saving to its own file. When I first saw the Registry, I was like, "Has Microsoft never heard of not putting all your eggs in one basket?!?" –  Mason Wheeler Sep 15 '10 at 17:05
1  
I think as a place for putting OS settings (like file extension registration, etc), it's fine. But if Microsoft published it as a read-only api, they would probably have been sued over it and had to make it writable anyways. –  µBio Sep 15 '10 at 17:17
    
@Chinmay, @Mason, the registry ISN'T a mistake because the registry does FAR more than just store configuration data (see: group policy, domains, replication). The mistake is how Microsoft pitched it to developers, and the lack of any good standard on how to use it. It ended up as a dumping ground for app data, which is not what it was ever meant for. –  Matt Olenik Sep 15 '10 at 19:40
show 2 more comments

In Windows, I would keep the application setting in AppData folder

share|improve this answer
add comment

My answer is a combination of Chinmay Kanchi's answer and BioBuckyBall's answer.

XML/Json for simple configurations, SQLite for complex, larger configurations parked on default OS application folder or default OS user folder when configurations are user dependent. Both could be used.

share|improve this answer
add comment

User settings are usually in

/home/<user>/.<application> 

So for example for irssi settings are /home//.irssi/config

share|improve this answer
    
But this is a Unix convention. What about Windows? And in Linux, doesn't flood user home directory with subdirectories? Why not /home/<user>/etc/application? –  Lorenzo Sep 15 '10 at 16:03
    
@Lorenzo: Flooding the user's home directory is rarely a problem. –  Chinmay Kanchi Sep 15 '10 at 16:24
1  
Configuration settings are increasingly being moved to ~/.config/application to help keep things consolidated. I'm inclined to agree with this movement. –  greyfade Sep 15 '10 at 16:55
1  
@Lorenzo: This is exactly the same as the Windows convention of storing configuration files in AppData. –  greyfade Sep 15 '10 at 16:56
1  
@Chris: no way! :-) –  Lorenzo Sep 15 '10 at 20:30
show 3 more comments

The best portable solution I know of is the QSettings class of the Qt framework. It does all the platform-specific stuff automatically, you only have to store/fetch some key-value-pairs and you're done. You can also override the platform-specific default behaviour (e.g. Windows registry) and tell it to use a simple, portable INI file.

http://doc.qt.nokia.com/4.7/qsettings.html

Even if you don't use C++ and Qt, the documentation might contain some useful information about the different ways to store application settings.

share|improve this answer
add comment

I think it's best to use the preferred platform-specific mechanism. For example, on OS X, the preferred mechanism is to place a property list in ~/Library/Preferences, and the Cocoa API has a really simple interface for storing and retrieving settings from there.

If your app is cross-platform, you can abstract this away with a class or whatnot.

share|improve this answer
add comment

For Java apps I think gson is a good choice. Create your settings objects and use gson to convert them to JSON and vice versa. Has the advantage of being human readable instead of some serialized blob.

Edit: ok, so its maybe not so general...

share|improve this answer
add comment

If you are writing in .NET, you can use System.Environment.SpecialFolders to find out what folder locations you can use for saving configuration or even some data.

share|improve this answer
add comment

The only thing I write to the registry is the location of the app, so that installers and updaters can find it easily. Everything else is stored in files in /AppData/Company/App

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.