8

I have a small tool I'm designing which would require a configuration file of some sort. The configuration file in my case is really more of a database, but it needs to be lightweight, and if needed the end-user should find it easily editable. However, it also will contain a lot of things in it. (depending on certain factors, could be 1Mb or more)

I've decided I'd rather use plain ol' text, rather than trying to use SQLite or some such. However, with using text, I also have to deal with the variety of formats. So far, my options are

  • XML
  • JSON
  • Custom format

The data in my file is quite simple consisting for the most part of key-value type things. So, a custom format wouldn't be that difficult... but I'd rather not have to worry about writing the support for it. I've never seen JSON used for configuration files. And XML would bloat the file size substantially I think. (I also just has a dislike of XML in general).

What should I do in this case?

Factors to consider:

  • This configuration file can be uploaded to a web service(so size matters)
  • Users must be able to edit it by hand if necessary(ease of editing and reading matters)
  • Must be able to generate and process automatically (speed doesn't matter a lot, but not excessively slow)
  • The "keys" and "values" are plain strings, but must be escaped because they can contain anything. (unicode and escaping has to work easily)
  • Multiple configuration files. Basically, each config file is tied to one "project"
8
  • 10
    Configuration in .NET is a mature and well understood process... why re-invent the wheel?
    – MattDavey
    Commented Nov 11, 2012 at 8:56
  • 3
    Why are you not considering YAML? I think YAML is the best fit.
    – sawa
    Commented Nov 12, 2012 at 4:08
  • 1
    @sawa actually I've never heard of YAML. It looks rather interesting
    – Earlz
    Commented Nov 12, 2012 at 4:58
  • 5
    @Earlz and if needed the end-user should find it easily editable. However, it also will contain a lot of things in it. (depending on certain factors, could be 1Mb or more). You can't have your cake and eat it. 1MB files are by definition not easily editable. Either it's a database(even if small), and then SQL-lite is a good option or it's a config file(you shouldn't have 1MB of config).
    – Pieter B
    Commented Nov 12, 2012 at 8:28
  • 3
    What about INI files? They are the most common way of configuring applications in both Windows and UNIX-like systems.
    – sakisk
    Commented Oct 1, 2013 at 11:41

8 Answers 8

12

I think YAML is best fit for your case. To my understanding, YAML is the de facto standard format for configuration files that need to be edited by hand. Many programming languages have a library for reading and/or writing YAML. JSON is closely related to YAML, but is little bit less easier to write than YAML, and is used more for communication between web server and the client program.

1
  • 4
    De facto among whom? Commented Dec 22, 2013 at 15:56
6

If you use JSON, people won't be able to comment out bits of configuration to try different things. For me, that's a deal breaker.

It also means you can't provide a nicely commented sample configuration file for users to customize.

XML is standard and if you can provide a schema, your users will thank you.

1
  • 2
    +1 I was about to mention my bad experiences with JSON. It's not a valid "configuration" format: no comments, not really readable, easy to leave stranded commas in lists, does't handle references between config objects. YAML or XML are the real options.
    – jjmontes
    Commented Dec 20, 2013 at 15:47
5

After looking at your requirements, and seeing that you have a dislike for XML, I would advise you to go with JSON. I must admit that I've only dealt with XML and JSON, so I cannot speak for any other common configuration formats out there.

JSON is really easy to write, and if formatted correctly, easy to read. Google just LOVES JSON for configuration use in their tools. Also, JavaScript can turn it into objects natively.

2

A "properties" file is good for key/value as the format itself is key/value. It's simply 1 line per key/value. The first = sign in the line splits the key and value.

It will be smaller than an equivalent XML file since the only formatting is the "=" separator and the newline character. In an XML file the markup could take as much space as the content itself. It could literally mean the difference between a 1MB and 2MB upload. Compression helps but you are still ahead if you start small.

Existing libraries can handle access to property files. But it's so trivial you can make your own in a few minutes. Bells and whistles in under an hour.

IP=11.22.33.44
BuildNumber=5.02.004
MaxFrameRate=50
2

Some good answers here already. But if I were in your shoes, before throwing XML over board, I would consider the following points:

  • XML is very well supported by the .NET framework and third-party tools, for JSON you will have to choose a third-party library and see if it fulfills all your requirements.

  • if you need manual editing only for a few exceptional cases, then XML will probably suffer your needs. If there is lots of editing to be done, and your list of configuration options has a particular complexity, your users most probably need some kind of dialog based option / configuration application - which means, it does not matter if the underlying XML format is 100% user-friendly. If you don't want to write such a thing, at least you can recommend some kind of XML editor to your users. Tools like XML notepad or the XML tools for Notepad++ work well for lots of people.

  • I guess the chances are higher that your end users have seen some kind of XML before than the chances that they have seen JSON before - which will make it a little bit easier for them to grasp it (if they really have to)

  • JSON does not support comments, which can make manual editing a pain

  • if size gets really a problem for uploading the data to a web service, consider using data compression

Actually, if you think about this points, and you don't want to use XML anyway, then go with JSON instead. Using XML or JSON provides you already with standard ways of escaping strings, standard ways of extending your configuration structure afterwards, and ready-made libs for reading and writing those formats - there is no need to reinvent the wheel with any "custom format".

2
  • The big problem I have with XML is it is very verbose. If I have 2000 strings that are 20 characters in size, that's 40000 bytes, or 40K. Now add XML and the overhead of XML tags across everything can really add up. <MyString> and </MyString> adds up to 21 more characters per string. This is the problem I have with XML in this particular scenario where size matters, but isn't so important where binary or something would be required
    – Earlz
    Commented Nov 12, 2012 at 2:23
  • 1
    @Earlz: as I wrote above, if size really matters, why not try data compression (for example, with icsharpcode.net/OpenSource/SharpZipLib/Default.aspx)? And honestly, are you absolutely sure it matters in your scenario if the files have 40K or 80K?
    – Doc Brown
    Commented Nov 12, 2012 at 10:38
1

As far as configuration files go, "1Mb or more" is certainly on the large side, and the need to escape strings and maintain lots of matching quotes does not play well with humans. That is why for large configuration files that need to be maintained by humans you should definitely consider defining a custom format and building a custom parser. Here is an article on the subject of humans having to write XML: Humans should not have to grok XML.

When parsers and parser generators were in their infancy, you could make a case for not building a custom one by saying that building a custom language is too complex. Now that excellent and very simple parser generators have matured, there is no excuse: you can build a custom parser in a matter of a few hours, on par with the time it would take you to build a parser for an XML-based language*.

Here is a small tutorial explaining the process of building a custom parser with ANTLR. It is in Java, but ANTLR supports C# as well.


* Unless you go for deserialization-based conversion from XML, in which case building an XML-based parser would take less time, but your classes would need to have a "shape" that closely resembles your XML.

0

JSON is a good choice for its flexibility, ease of reading and editing outside your program, the wide availability of parse libraries to support it. It supports hierarchy, lends itself to simple forward / backward compatibility that a file that simply saves data in sequence doesn't. I think it also has easy techniques for converting between Java classes and file data and then back the other way. A lot of people know and have coded for this format, and the format is important for other programs that you will probably need to work with in the future.

Many systems were based on .ini format, and they are pretty easy to parse if you were writing a parser from scratch.

csv can be quick to code and works with very little overhead, but has issues with flexibility, forward/backward compatibility.

Using the registry was a common practice in Windows.

Using cookies is common for web development.

For a utility function, maybe just use free format text that matches your command line options, just read it in and make an argv string array from it.

0

Don't use XML.

XML is a markup language. When used for serialization or configuration language, XML has a fundamental problem, namely that attributes and text contents of an element can describe the same thing. You need to decide between attributes and text contents. Furthermore, XML is needlessly verbose, needing e.g. specifying the element name twice (open, close).

Use XML for what it's meant: as a markup language. Configuration files do not require a markup language.

Don't use JSON either.

JSON is wonderful as data serialization format. However, JSON lacks commenting. That, to me, is a deal breaker. Furthermore, you need to escape all occurrences of the " character.

Don't use INI.

INI files have a fundamental problem: they lack nested data structures. The only notion of nesting is that a tag can have a number of attributes. That's only 1 level of nesting. In real life use cases, I have found this limitation extremely annoying. I have worked as a part of a project where the configuration was in INI files, and the pains are major.

Use a custom language if feasible.

If you have access to parser generator tools such as Lex & Yacc, do use a custom language. I'm not sure what's the state for parser generators on .NET, but for C code, I would choose Lex & Yacc. The learning curve in the beginning may be a bit steep (Lex & Yacc aren't the easiest of tools to use), but the time invested for learning is totally worth it.

If custom language not feasible, use YAML.

YAML, as the name says, ain't markup language. It is a serialization language that happens to be due to its properties acceptable for configuration files, because it supports comments. YAML isn't needlessly verbose like XML: it doesn't require specifying the element name twice (open, close). YAML doesn't have the attribute vs. text contents problem of XML.

Consider pro.per.ty=value as well.

If you want an INI-like configuration, where nesting is supported, consider a format consisting of pro.per.ty=value pairs (key-value pairs), where the key can have a number of nested levels, using the . character as the separator.

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