locked
What is Configuration Data? How is it related to Configuration Files? How is it related to Application Settings? When do you use it? RRS feed

  • Question

  • I'm new to writing programs that use information provided at runtime. I've come across use cases where I'd like my application to read from a file to know what to do instead of prompting for user input.

    For example, a C# application that takes data from a specific directory and processes it (where the C# application does other things like continually monitors the data files in that directory for changes, inserts the data into a database, or runs computation against them -- in essence that program needs to run for a long period of time). Now, that application should perform its duties given any system path to the directory containing the data files and let's say the path doesn't change often (say once every month, when the user wants the program to perform its duties on a different directory). 

    One option is to have that C# program periodically read from and parse a plain-text file containing the directory to be examined. The plain-text file might contain a line that looks like this:

    Data Directory: C:\Users\Alice\Data\TemperatureSensor Operation: RunningSum User Name: Alice

    Alternatively, the C# program can periodically query for the Data Directory to examine, the computation operation to be done, and for the username (blocking all other functionality such as database insertions, etc...) until the user steps in to provide that information. This is undesirable in my use-case. 

    Is there a C# library that manages program access of such plain-text files, does the parsing for me, and updates the application variables (e.g., the string variable that stores where the C# application should look for data) as soon as it is changed by the user (so the plain-text file is human-readable, the user can change field values to affect the program behavior)? 

    I believe such plain-text files are called Configuration files but I'm hesitant to use that term since it could mean something else/be called something else in the .NET framework. Should I look at the System.Configuration API? 


    • Edited by Minh T Wednesday, August 29, 2018 5:05 PM
    Wednesday, August 29, 2018 5:03 PM

All replies

  • "Is there a C# library that manages program access of such plain-text files, does the parsing for me, and updates the application variables"

    Yes and no. .NET has support for reading text files. Depending upon how you want to do it you can use File.ReadAllText or File.ReadAllLines in the simplest case. Refer to this MSDN article on the options. But what you do with it once read is completely app-specific so you'll have to decide how to proceed and write that code yourself. 

    For the parsing of a file, if you use a non-standard format like you've posted then you're going to have to parse it yourself. Parsing can be simple or complex, depending upon your format. In your very specific example you can simply use String.Split to split each line of the file. For example the following code would read the file you mentioned earlier.

    var lines = File.ReadAllLines("MyFile.txt");
    foreach (var line in lines)
    {
       //Parse
       var tokens = String.Split(':');
       var key = tokens[0];
       var value = tokens[1];
    };

    In the above example your app would then need to decide what to do with the key/value pair. Of course no error checking is happening here either. Since your example file is breaking up (what we'd normally consider to be) a record across multiple your app is responsible for identifying where one record ends and another begins.

    If you're using a more standard file format like CSV or JSON then there are libraries you can use to read the "records" easily. No file parsing is required. It depends upon how simple or complex you want your format to be.

    "I believe such plain-text files are called Configuration files:"

    No. A configuration file in .NET is generally a .config file that is an XML-based file that is managed by the underlying configuration subsystem and accessed via ConfigurationManager. You don't read the file directly because .NET handles it. It is a complex, but flexible, format. More importantly however it is really designed to store application-level stuff that doesn't change outside of deployment. Changing that file while the app is running isn't going to work out of the box. You have to go through some extra steps such that it is exceedingly rare that an app would try to write to its own config file. 

    Note that for a standard application using a regular installer then your app won't actually have write permissions to its folder so you cannot modify any apps that are part of your application deployment, including the App_Data folder you may try to create. To adjust this you'd have to modify your installer to set up security properly. For most apps, if you need to store data while the app runs you would use a database if the data needs to be shared across users and persisted. If the data is per user then a per-user config file can be used or an arbitrary data file stored in the user's Documents directory. 

    As for your app it really depends what type of app it is and how often the data changes. If your app is run on demand or a schedule and you want to adjust its data then you'd normally just use command line arguments. This allows the app to be scripted. If your app is more of a driver that runs other apps then a file is doable but not flexible. At a minimum you'd need to use FileSystemWatcher to monitor the file for changes. This can get pretty complicated depending upon how the file is written and FSW itself can be a little frustrating until you understand how it works. But if your app is a long-running app and that data is coming from other apps then a database would probably be a better route. It also depends upon what you do with the data when you're done with it. You don't really want multiple apps updating the same file at the same time. Issues will occur.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, August 29, 2018 5:33 PM
  • Thank you for the thoughtful response, CoolDadTx. It tied together a lot of things I'd come across but haven't delved too deep into. 

    Some more research about whether the .NET Framework supports INI files yielded this: 

       https://stackoverflow.com/a/217910/3396951

    in which David Arno, the author of the accepted answer, states that the .NET Framework doesn't provide native support for INI file parsing. 

    The configuration files I've looked at looks like what you'd find in a .INI file. I'm not tied to a particular way of formatting the configuration file but I'm eager to use what's already provided by the .NET Framework. I'm inclined to use the ConfigurationManager, but it looks like I'll have to dig into the Configuration API to define custom behavior. 

    As for your app it really depends what type of app it is and how often the data changes. I

    The app is more of a "driver" application and not one of those "fire and forget" programs.  After installation, it'll need to run when the computer starts up and continue running until stopped and it will need to monitor changes to data files. 

    It sounds like I'll need FileSystemWatcher to trigger program behavior when data file changes and when the .config file changes. 


    Wednesday, August 29, 2018 7:31 PM
  • .NET doesn't have INI support out of the box but there are quite a few good libraries to support it. You're example file isn't really a Windows INI file though. INI files in the most general sense are key-value pairs. At least in Windows you can have sections to group related items together. Games and Windows drivers go this route. 

    Based upon your description I don't know that the config file is the best option. Config files should be for data that can be configured at deployment but not change thereafter. Since it is unclear what you're trying to drive but it sounds like you don't want a database involved then I might recommend a simple drop directory approach instead. Using FSW monitor a particular directory on the machine. "Applications" that you want to run in your driver can drop files into this folder. The FSW will pick this up as they appear in the directory and your driver app can then perform whatever feature you want. For the files themselves they can be as simple as an INI file but if you need a little more complexity then XML or JSON would be a better option. Irrelevant the driver would just be watching the directory so you won't run into issues with colliding files or whatnot. Even better is that if your driver goes down and restarts it can start "processing" any apps that dropped files there while it was down. Of course your driver app will want to remove or otherwise mark files as processed when it is done. Moving them to some other folder or deleting them seems reasonable.

    If you want to move up the complexity scale then you can consider using a messaging system or WCF/REST API instead. These would require your app to be running but would allow client apps to send requests to your driver. This is the more enterprise level solution but is what is typically done in most systems. Instead of dropping files the clients would make a method call across the network (or machine) to your service that is listening. It would then process the request. It is unclear at this point that such a system is the right fit for your problem but I at least wanted to mention it in case it comes up later.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, August 30, 2018 2:03 AM