John Humphreys
John Humphreys

Reputation: 39264

C# .NET - method to store some very small scale persistent information?

I have an application that will need extremely little persistent storage. Realistically, we're talking about < 30 integers. All the application needs is to know those integers on next startup (and the integers do change as it runs).

A database is overkill for this, but I don't particularly want to just use a text file either.

Does C# have any mechanism for persisting small values like this between runs? I've noticed you can store things in resource files and some other places - I don't know if you can change those in the runtime though. I'm just learning C# & .NET for a new job, so apologies if this is a silly question!

Upvotes: 27

Views: 30557

Answers (7)

user1172763
user1172763

Reputation: 306

I've long been amused by this question, which originally didn't mention the "just use a file" possibility, but seemed purposefully constructed to have us yelling "just use a file!" at our monitors.

I have to make a living in this field, so I tend to bite my tongue at this sort of quasi-architectural pearl-clutching. Some of the top answers are just so wrong-headed, though, that I can remain silent no more.

Settings.settings is an architectural boondoggle that is conspicuously absent from any real, production .NET code I've ever seen (and I've seen a lot). In particular it breaks down with respect to application version number changes. Yeah, there's a workaround, but you have to pick through a lot of OO detritus to get there.

SQLite... where do I even start? Who looks at an even halfway-modern codebase, needs to do what OP is asking about, and thinks, "you know, what would really help here is to inject an entire relational database written in C, twenty years ago, right here into my own thread"?

The right answer here is to do what Settings.settings does (i.e. put a file into the folder where Windows wants you to put application files) without using Settings.settings.

Upvotes: 0

Ghominejad
Ghominejad

Reputation: 1798

You can use IMemoryCache and AcroFS library as an additional layer for persistence!

All you need is calling .Persistent() method to obtain the persistent instance of the memory cache.

_memoryCache
   .Persistent()
   .Set(key, value, TimeSpan.FromMinutes(1));

If you don't need to cache you can simply use AcroFS without IMemoryCache :

var _repository = FileStore.CreateStore();

// store the model with a custpm key
_repository.Store("my-model", MyModel);

// load model
var model = _repository.Load<MyModel>("my-model");

Upvotes: 0

oatsoda
oatsoda

Reputation: 2178

If you're using c# 4.0 and upwards, you might want to have a look at the new Memory Mapped Files.

Using Persisted Memory Mapped files will give you the ease of a file, but the speed of being mapped into memory. You would of course still have to manage the file format yourself.

  • Persisted memory-mapped files

Persisted files are memory-mapped files that are associated with a source file on a disk. When the last process has finished working with the file, the data is saved to the source file on the disk. These memory-mapped files are suitable for working with extremely large source files.

This probably may be overkill for 30 integers, but it's another option, especially if speed is key.

Upvotes: 4

balexandre
balexandre

Reputation: 75073

I would choose file storage and avoid database or registry as the first it needs to much of the framework and the second ... ohh well, never play with Registry :)

using XML as a file storage this is a great read:

How does one parse XML files?

you can create your file to save all ID's in the same node, or write one ID per node, it's up to you, something like this would be fine:

<?xml version="1.0" encoding="utf-8" ?> 
<settings>
    <selected>
        <id>1</id>
        <id>8</id>
        <id>12</id>
        <id>15</id>
    </selected>
</settings>

In order to create such file:

  XmlDocument doc = new XmlDocument();
  XmlElement set = (XmlElement)doc.AppendChild(doc.CreateElement("settings"));
  XmlElement sel = (XmlElement)set.AppendChild(doc.CreateElement("selected"));

  int[] selectedIds = new int[] { 1, 2, 3, 4, 5 };

  foreach (int id in selectedIds)
     sel.AppendChild(doc.CreateElement("id")).InnerText = id.ToString();

  string path = Path.GetDirectoryName(Application.ExecutablePath);
  doc.Save(path + "/settings.xml");

In order to read you can use XmlReader, XmlTextReader, XDocument, etc...

Upvotes: 3

Zachary
Zachary

Reputation: 6532

Here is a blurp of another SO post that explains how to setup Application Settings, this is a simple file based solution for reading/writing values.

"If you work with Visual Studio then it is pretty easy to get persistable settings. Right click on the project in Solution Explorer, choose Properties. Select the Settings tab, click on the hyperlink if settings doesn't exist. Use the Settings tab to create application settings. Visual Studio creates the files Settings.settings and Settings.Designer.settings that contain the singleton class Settings inherited from ApplicationSettingsBase. You can access this class from your code to read/write application settings:"

Settings.Default["SomeProperty"] = "Some Value";
Settings.Default.Save(); // Saves settings in application configuration file

Upvotes: 28

Steve Danner
Steve Danner

Reputation: 22148

You could just serialize the list to an xml file. This is how you save it:

var xs = new System.Xml.Serialization.XmlSerializer(typeof(List<int>));
List<int> ints = new List<int> { 1, 2, 3 };

using (FileStream fs = new FileStream(@"C:\store.xml", FileMode.OpenOrCreate))
{
    xs.Serialize(fs, ints); 
}

And retrieving it is equally easy:

using (FileStream fs = new FileStream(@"C:\store.xml", FileMode.OpenOrCreate))
{
    ints = xs.Deserialize(fs) as List<int>;
}

Upvotes: 6

Nesim Razon
Nesim Razon

Reputation: 9794

I would use embeeded sqlite database.

http://www.codeproject.com/Articles/22165/Using-SQLite-in-your-C-Application

SQLite is a small, fast and embeddable database where the database engine and the interface are combined into a single library. It also has the ability to store all the data in a single file. So if your application requires a standalone database, SQLite is perhaps the perfect choice for you. There are, of course, other reasons for choosing SQLite including:

SQLite has a small memory footprint and only a single library is required to access databases, making it ideal for embedded database applications. SQLite has been ported to many platforms and runs even on Windows CE and Palm OS. SQLite is ACID-compliant, meeting all four criteria - Atomicity, Consistency, Isolation, and Durability. SQLite implements a large subset of the ANSI-92 SQL standard, including views, sub-queries and triggers. No problem of extra database drivers, ODBC configuration required. Just include the library and the data file with your application. SQLite has native language APIs for C/C++, PHP, Perl, Python, Tcl etc. Native API for C# is still not present.

Upvotes: 6

Related Questions