views:

283

answers:

5

I'm using Visual C#.NET, and am making an app that uses winforms. I essentially need to open multiple files as strings, and manipulate the data in various places without saving the information back to the file. How do I go about storing this data so that I may use it in various parts of my code?

+3  A: 

Create a singleton which contains the file strings as public properties, and make the singleton public.

http://msdn.microsoft.com/en-us/library/ms998558.aspx

Ten Ton Gorilla
It'll work (at least until you have multiple threads), but overuse of singletons are usually a sign of design problems up the road...
Marc Gravell
Make sure you create a singleton and not a *S*ingleton. http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
dss539
Is there any reason to think the singletons are being overused? Speculating on what might cause a problem in a application whose context we know nothing about seems rather specious.
Russell Steen
@Russell - simply: loading data as a file is not something that **by definition** can only exist once at a time. Therefore: overused. At some point you could validly consider loading two models from different files - perhaps "before" and "after" on side-by-side screens. With a singleton (or static properties) you're scuppered. Or alternatively you might want to refactor the app onto a web-server / SaaS (which are highly-threaded).
Marc Gravell
Singletons always might cause a problem; just like int x = 5/y might cause a problem if you don't check for y==0. Marc is just giving the guy a heads-up that singletons suck for multithreading unless you consciously deal with the synchronization issues.
dss539
Before crying out "singleton" every time one needs a piece of information in two places, make sure you have read "Singleton considered stupid", here: http://steve.yegge.googlepages.com/singleton-considered-stupid
Doc Brown
@Marc - I agree with your point. And as you stated it, it is much more useful than "overuse of singletons are usually a sign of design problems up the road", which is a pretty useless statement. It's also a different problem. "This problem is bad for singletons" with an explanation is much more useful (and different than) than "Overuse of singletons is bad". If your point is that singletons are generally an overused design pattern... start a wiki instead of hijacking a question.
Russell Steen
Understanding whether it is appropriate to use a singleton or not is *central* to my comment on your answer. In this case I see no sensible reason to introduce the issues associated with singletons, especially as it is clear that the state is intended to me mutable. I see no hijacking - just healthy conversation about a design decision that could have implications that the OP can't yet see.
Marc Gravell
A: 

I'd probably use a static class, unless there are other requirements you didn't mention.

public static class MyFilesAsStrings
{
    public static String FirstFile {get;set;}

    public static LoadData() 
    {
        FirstFile = System.IO.File.ReadAllText(@"C:\Temp\MyFile.dat");
        // and so on
    }
}
Nate Bross
This will be hard to unit test. Please, don't do it. Think of the children!
dss539
I fail to see how, call LoadData() and then make assertions based on the properties of the static class. It will be as testable as any other option that doesn't involve creating a seperate DataModel class, which would be the best solution, but doesn't answer the OP's question, it simply provides a different aproach.
Nate Bross
A: 

Why open them "as strings"? Strings in .NET are immutable, so it could get expensive if you are making lots of changes. The normal approach would be to parse / deserialize the data out into an object model, and pass that object model into your forms - i.e.

MyModel model = MyModel.Load(path);
MyForm form = new MyForm();
form.Model = model;

or similar. Then your form can access properties of the model:

captionTextBox.Text = model.Title; // etc

or use data-binding if you really want:

captionTextBox.DataBindings.Add("Text", model, "Title");

(which will enable 1-way or 2-way binding, depending on whether your model also provides change-notifications)

Marc Gravell
Marc, I do like this suggestion, but I am concerned that the data cannot be reasonably parsed into predictable/usable properties. Nevertheless, wouldn't an object model still require me to use string as properties, to store the data in memory?
Brandon
Similarly, do you have any links that explain implementation of this sort? I am not a C# programmer by trade, but do need to utilize it for this pet project at work.
Brandon
@Brandon The number 4294967295 can be stored as A) `string` which uses 10 bytes or B) `UInt32` which uses 4 bytes. 4 < 10 ;)
dss539
@dss539: Good point. Unfortunately I'll be dealing almost exclusively with text/number variations that cannot be predicted/assumed.
Brandon
@Brandon Good luck with that. :(
dss539
If you can't predict it - they maybe just use the `Stream` directly? or remap to a `MemoryStream` if you need to be able to change size.
Marc Gravell
A: 

There are a number of approaches you could take.

If the files are small to medium sized, you could load the contents into a StringBuilder or a StringWriter and store these in a Dictionary indexed by file name.

If the files are large, you could do this, but you might need to consider saving the contents of the StringWriter to a temporary file while working with them, and reload from the temporary file as needed.

If the files are huge, you would read only parts, or pages, from the file, and manage those in the same way as the small files, except there'd be many per individual file on disk, and so you might store them in a List or similar.

There's also always the "copy-to-temp-file-edit-then-copy-back" approach. Simple, easy and effective, even if it does use the disk a lot.

codekaizen
A: 

I'm not sure that I understand what a Singleton gives you in this situation, other than ensuring you don't have multiple copies of the strings hanging around. It does nothing to help with modifying the strings themselves.

The way I read your question is that the manipulation of the strings in memory (without writing back to a file) is critical. Based on this there are two main options, StringBuilder and MemoryStream.

StringBuilder is specifically designed to allow you to efficiently modify or append to data represented as a string. If the file is not too large for it to fit in memory, StringBuilder is the best choice.

You simply pass the contents of the file to the StringBuilder constructor. Then utilize methods such as Append(), Insert(), Remove(), Replace() or the indexer [] to modify the string data as needed. The Stringbuilder ensures that these operations are much more efficient than doing the same on a standard string.

You could also load the file into a MemoryStream and then use a StringReader (or StringWriter) to get a Stream like interface (Read(), Peek(), ReadLine() etc) for manipulating the string.

It's a bit more work than StringBuilder, but may be preferred if a Stream style approach fits better with your application.

Ash