C#: a mechanism to generate regular files - c#

following regular files (date_time.zip) would be generated at 15-min interval in ASP.NET site with Timer.
1027_0100.zip, 1027_011*.zip, 1027_0130.zip, ...
My question is I need a mechanism to restore files which are somehow missed within 3 days, like 1026_0000.zip. What data structure/algorithm would you recommend to use to implement?
PS: I intend to use another Timer to regularly restore missing files.
Thank you!

Since the naming scheme is know and the where the files are going is know. You simply need to generate what would be the name for each potential file and then check its existence using the System.Io.file.Exists. If that call fails regenerate the file.

I'll propose a slightly different solution: rather than querying the disk repeatedly, just use Directory.GetFiles(...) and Linq against that:
string[] files_that_should_exist = YourMethodToGenerateExistingFilenames();
string[] files_in_dir = System.IO.Directory.GetFiles(output_path);
var missing_files = files_that_should_exist.Except(files_in_dir);
foreach(string file in missing_files) YourMissingFileGenerateMethod(file);

Related

save Website Content & access it

I'm starting with C# again after 3 years (have average experience with object orientated languages; here I'm mainly missing function names). I'm not too sure it's possible in c#, so if you can recommend another language I will try to look there.
My Question(s):
On program start (or button) I want to extract a part of a Website and save it (temporary of file don't matter). That way I wont need to buffer/load (loadtime) anything again and can access the content if I go offline afterward.
I want to extract some numbers out of the content and do simple math with them.
Would be great to know if its possible and how. I'm happy if you can tell me the main functions I should look into. Some basic code would be great too if its not too much to ask.
If you want to have access to the information even if your program closes/restarts then you will need to export the source code to a file as follows:
using (WebClient wb = new WebClient())
{
string source = wb.DownloadString("http://example.com");
File.WriteAllText("c:\\exampleFile.txt", source);
}
Otherwise you can remove the File.WriteAllText("c:\\exampleFile.txt", source); and simply parse the parts you want from the source and do your calculations.
Keep in mind this will download the source code of the url as 'it is' that means you will need to do some parsing of the text in order to get the information you want out of it.
May be you are looking for this:
var contents = new System.Net.WebClient().DownloadString(url);

How to save variable values on program exit?

I am trying to use an ArrayList to store a variable number of strings, and would like to know how to save the ArrayList and its elements so that my windows form can recall their value between program load and exit.
I used to store the information in a text file, but would like to avoid external files if possible.
Thank you for any help you could provide.
You can save the ArrayList (if not ArrayList their are other equivalent classes) using Properties.Settings best part is it allows you the setting variable at Application and user level
A very good example can be found here how to use Settigns http://www.codeproject.com/Articles/17659/How-To-Use-the-Settings-Class-in-C
I've always done using (In Winforms in your case from the sounds of it), the Form_Closing to store to a Properties.Settings variable you'd create beforehand. If it's an ArrayList, you could store it to XML or a comma separated list. Your serizliation/deserialization method will depend on your data.
Have a look at isolated storage.
I used to store the information in a text file, but would like to avoid external files if possible.
Inevitably storing data between runs will require something outside the program's executables.
The registry would work, but the registry is not great for storing anything more than a small amount of information. A database could be used by that adds files.
For text strings a text file – one string per line1 – can be saved and loaded in a single statement. Putting the file into isolated storage or under a dedicated folder in %AppData% limits the chances of a user messing it up.2.
// Load
var theStrings = new ArrayList();
var path = GetSavePath();
if (File.Exists(path)) {
theStrings.AddRange(File.ReadLines(path);
}
// Save:
File.WriteAllLines(GetSavePath(), theStrings.ToArray());
Here using ToArray() as ArrayList doesn't implement IEnumerable<String> (List<String> would be a better choice for a collection and avoid this).
1 This assumes end of line is not valid inside the strings. If this needs to be supported there are a number of options. Some file format to separate the strings by another mechanism, or perhaps the easiest will be to escape characters with a simple transform (eg. \ → \\, newline → \n, and carriage return → \r).
2 You cannot prevent this without significant additional complexity that would use something like a service to load/save as a different user thus allowing the data to be protected by an ACL.

Having trouble saving multiple items to Isolated Storage

I have a noteapp, two pages:
MainPage.xaml — the creation of notes;
NoteList.xaml — a list of notes.
Notes are saved by means of IsolatedStorage, and appear in NoteList.xaml (listbox), but notes with the same name is not stored, how to fix it?
I need to be able to add notes with the same name (but with different content).
Thanks!
Are you using the note name as the file name? If so... don't do that. Save each file with a unique name. There are myriad ways of doing this. You could use a GUID or a timestamp, or you could append a timestamp to the end of the file name. If you were so inclined you could store all of the notes in a single formatted file-- perhaps XML.
What you need is a way to uniquely identify each note without using:
a. The note's name
b. The note's contents
While using a timestamp might make sense for your application right now (since a user probably cannot create two disparate notes simultaneously), using a timestamp to identify each note could lead to problems down the line if you wanted to implement say... a server side component to your application. What happens if in version 23 of your application (which obviously sells millions in the first months), you decide to allow users to collaborate on notes, and a Note is shared between two instances of your app where they happened to be created at the EXACT same time? You'd have problems.
A reasonable solution to finding a unique identifier for each Note in your application is through the use of the Guid.NewGuid method. You should do this when the user decides to "save" the note (or if your app saves the note the moment it's created, or at some set interval to allow for instant "drafts".
Now that we've sufficiently determined a method of uniquely identifying each Note that your application will allow a user to create, we need to think about how that data should be stored.
A great way to do this is through the use of XmlSerializer, or better yet using the third party library Json.Net. But for the sake of simplicity, I recommend doing something a bit easier.
A simpler method (using good ole' plain text) would be the following:
1: {Note.Name}
2: {Guid.ToString()}
3: {Note.Contents}
4: {Some delimiter}
When you are reading the file from IsolatedStorage, you would read through the file line by line, considering each "chunk" of lines between the start of the file and each {Some delimiter} and the end of the file to be the data for one "Note".
Keep in mind there are some restrictions with this format. Mainly, you have to keep the user from having the last part of their note's contents be equal to the {Some delimiter} (which you are free to arbitrarily define btw). To this end, it may be helpful to use a string of characters the user is not likely to enter, such as "##&&ENDOFNOTE&&##" Regardless of how unlikely it is the user will type that in, you need to check to make sure before you save to IsolatedStorage that the end of the Note does not contain this string, because it will break your file format.
If you want a simple solution that works, use the above method. If you want a good solution that's scalable, use JSON or XML and figure out a file format that makes sense to you. I highly encourage you to look into JSON, it's value reaches so much further than this isolated scenario.
I've had a need to write notes to IsolatedStorage. What I did was to them them to a file.IsolatedStorageFile I write date on which the note was written and then note. From the list box i store them to two arrays. Then before exiting the app, write them to a file.
try
{
using (IsolatedStorageFile storagefile = IsolatedStorageFile.GetUserStoreForApplication())
{
if (storagefile.FileExists("NotesFile"))
{
using (IsolatedStorageFileStream fileStream = storagefile.OpenFile("NotesFile", FileMode.Open, FileAccess.ReadWrite))
{
StreamWriter writer = new StreamWriter(fileStream);
for (int i = 0; i < m_noteCount; i++)
{
//writer.Write(m_arrNoteDate[i].ToShortDateString());
writer.Write(m_arrNoteDate[i].ToString("d", CultureInfo.InvariantCulture));
writer.Write(" ");
writer.Write(m_arrNoteString[i]);
writer.WriteLine("~`");
}
writer.Close();
}
}

Equivalent to HashSet.Contains that returns HashSet or index?

I have a large list of emails that I need to check test to see if they contain a string. I only need to do this once. I originally only need to check to see if they email matched any of the emails from a list of emails.
I was using if(ListOfEmailsToRemoveHashSet.Contains(email)) { Discard(email); }
This worked great, but now I need to check for partial matches, so I am trying to invert it, but if I used the same method, I would be testing it like...
if (ListOfEmailsHashSet.Contains(badstring). Obviously that tells me which string is being found, but not which index in the hashset contains the bad string.
I can't see any way of making this work while still being fast.
Does anyone know of a function I can use that will return the HashSet of matches, the index of a matched item, or any way around this?
I only need to do this once.
If this is the case, performance shouldn't really be a consideration. Something like this should work:
if(StringsToDisallow.Any(be => email.Contains(be))) {...}
On a side note, you may want to consider using Regular Expressions rather than a straight black-list of contained strings. They'll give you a much more powerful, flexible way to find matches.
If performance does turn out to be an issue after all, you'll have to find a data structure that works better for full-text searching. It might be best to leverage an existing tool like Lucene.NET.
Just a note here, We had a program that was tasked with uploading excess of 100,000 pdf/excel/doc etc, everytime the file was uploaded an entry was made in a text file. Every Night when the program ran it would read this file, load the records and add it to the static HashSet<string> FilesVisited = new HashSet<string>(); FilesVisited.Add(reader.ReadLine());.
When the program attempted to upload a file, we had to first scan through the HashSet to see if we already worked on the file. What we found was that
if (!FilesVisited.Contains(newFilePath))... would take a lot of time and would not give us the correct results (even if the file path was in there) alternately, FilesVisited.Any(m => m.Contains(newFilePath)) was also a slow operation.
The best way we found to be fast was the traditional way of
foreach (var item in FilesVisited)
{
if (item.Contains(fileName)) {
alreadyUploded = true;
break;
}
}
Just thought I would share this....

Implementing a save function in a C# image manipulation app

I started thinking about how to handle the save functionality of my app, and thought about 2 options:
The application has nodes like:
Blur
Contrast
Sharpen
Invert
...
1. Interpreting the saved file, like:
Blur name:"Blur01" Amount:5
...
2. Having the saved file in a self executable format, like:
Blur blur = new Blur ();
blur.Name = "Blur01"
blur.Amount = 5
...
Which one should I go for? Is there a better way to handle this?
I want the saved file to be backwards and forwards compatible.
EDIT: Thanks for all the replies. Anyone can please explain why #2 would not be future proof? Is it because one can change the load/open code for #1, but not for #2?
You could probably use XML Serialization, since it's widely accepted and human readable.
Here's a tutorial on that: XML Serialization
I would go with something more like the first option.
Although, in general, I think XML would be a better approach to this than making your own syntax. This is much better from a compatibility/future-proofing standpoint than trying to make your own syntax parsers for your file.
What about something like:
<Filters>
<Blur Name="Blur01" />
<Sharpen Name="Sharpen01" Amount=5 />
</Filters>
I too would go with an XML file as this will allow you to ensure compatibility both forwards and backwards.
This is because you look for properties rather than parsing the file line by line.
For example, if blur changes from:
<Blur>
<name>Blur01</name>
<amount>5</amount>
</Blur>
to:
<Blur>
<name>Blur01</name>
<amount>5</amount>
<feather>true</feather>
</Blur>
Older versions of the app will still be able to read the file as they won't look for the feather property. All you need to do is ensure that you set default values when you create your objects so that the older files can be read without leaving unset data.
In response to the update - there's no reason why you couldn't make #2 future proof. You'd just have to do the versioning yourself.
The reason having a self-executing "save format" is generally bad is that today your "Blur" function might look like:
public class Blur
{
int Amount = 5;
}
but in the future, you might improve your blur "system" to instead have something like:
public class Blur
{
int HorizontalAmount = 5;
int VerticalAmount = 10;
}
and now when you execute that saved file, it will no longer compile because there is no longer an 'Amount' property. Then to get backwards compatibility you will need to 'interpret' the Amount value to now mean HorizontalAmount = 5 AND VerticalAmount = 5 (or whatever).
So really, in the long run, you will be better off by having an interpreted file format from the start.
Are you saving it in a text file?
If that is so wouldn't it be better to save it as XML?
<Blur>
<name>Blur01</name>
<amount>5</amount>
</Blur>
Otherwise I am not sure I understand the question :)

Categories