Save small data in application - c#

I want to save some small pieces of information which change simultaneously every second. But the problem is where I can save it?
I tried to save in application setting & xml file tab. But when applications quit all data get corrupted. Because it won't save. The same issues like when the electricity went out, normal problem in my country. This is also corrupt stored information.
I am wondering to save in database but its quite small information and I don't think to use whole database for it.

Use SQLite as a local storage database. You can save the data using Transaction. Using transaction can help you get rid of data corruption problem.

You can also use SQL Express. It is integrated into VS environment so it's very easy to setup in your project. It is simply a file-based version of SQL you can add to your project and then design through Visual Studio. Step-by-step instructions are here: http://msdn.microsoft.com/en-us/library/ms233763(v=vs.80).aspx

Since you mention in a comment that you're only storing 2 variables, a database is probably an overkill. Instead create a class that will round-robin write to two separate files, always picking the older one of the files to write to, as long as the newer one is valid. That way if one of the files gets corrupt, you can revert to the older "version" based on file modified timestamp. You can pick your favorite file format and verify when loading that the file is not corrupt. Your read/write logic can be like follows:
Reads:
Read the newer file.
If corrupt, read the older file.
Writes:
Read the newer file. If corrupt, overwrite it. This is to make sure you don't overwrite the old one when the new one was already corrupt, ending with two corrupt files.
If not corrupt, overwrite the older file. This makes sure if you corrupt the older file, you still have the newer file's values.

Related

C#, can I save a file from a stream or other to my single exe?

I would like to take a serialized file and save it to my recourses folder in project.
My reason for doing this (maybe there's a better way) is I have a published exe (single executable file) for the program that runs and when it creates a serialized file I don't want it to save it to desktop. I need to somehow save it to my exe without going outside of it.
Any advice on how I could do this?
It's very ugly.....but you could use an "alternative data stream" on NTFS system.
http://ntfs.com/ntfs-multiple.htm
https://learn.microsoft.com/en-us/sysinternals/downloads/streams
How to read and modify NTFS Alternate Data Streams using .NET
https://blogs.msmvps.com/bsonnino/2016/11/24/alternate-data-streams-in-c/
https://oddvar.moe/2018/04/11/putting-data-in-alternate-data-streams-and-how-to-execute-it-part-2/
https://blog.foldersecurityviewer.com/ntfs-alternate-data-streams-the-good-and-the-bad/
https://www.irongeek.com/i.php?page=security/altds
You'll probably have security scanners stopping you from doing it.
In addition if you copy the from an NTFS volume to say FAT, then alternative data streams are lost.
Also some backup software may not backup ADS properly.
https://wiki.sep.de/wiki/index.php/Support_for_NTFS_alternate_data_streams_(ADS)_for_Windows
https://www.2brightsparks.com/resources/articles/ntfs-alternate-data-stream-ads.html
https://community.osr.com/discussion/89308/alternate-data-streams-and-backups
https://social.technet.microsoft.com/Forums/Azure/en-US/007d5442-1cd8-4293-b717-b8fa72606189/ntfs-data-streams-broken-by-design-on-file-copy?forum=winserverfiles

Can you pre-compress data files to be inserted into a zip file at a later time to improve performance?

As part of our installer build, we have to zip thousands of large data files into about ten or twenty 'packages' with a few hundred (or even thousands of) files in each which are all dependent on being kept with the other files in the package. (They are versioned together if you will.)
Then during the actual install, the user selects which packages they want included on their system. This also lets them download updates to the packages from our site as one large, versioned file rather than asking them to download thousands of individual ones which could also lead to them being out of sync with others in the same package.
Since these are data files, some of them change regularly during the design and coding stages, meaning we then have to re-compress all files in that particular zip package, even if only one file has changed. This makes the packaging step of our installer build take well over an hour each time, with most of that going to re-compressing things that we haven't touched.
We've looked into leaving the zip packages alone, then replacing specific files inside them, but inserting and removing large files from the middle of a zip doesn't give us that much of a performance boost. (A little, but not enough that its worth it.)
I'm wondering if its possible to pre-process files down into a cached raw 'compressed state' that matches how it would be written to the zip package, but only the data itself, not the zip header info, etc.
My thinking is if that is possible, during our build step, we would first look for any data file that doesn't have a compressed cache associated with it, and if not, we would compress that file and write the result to the cache.
Next we would simply append all of the caches together in a file stream, adding any appropriate zip header needed for the files.
This would mean we are still recreating the entire zip during each build, but we are only recompressing data that has changed. The rest would just be written as-is which is very fast since it is a straight write-to-disk. And if a data file changes, its cache is destroyed, so next build-pass it would be recreated.
However, I'm not sure such a thing is possible. Is it, and if so, is there any documentation to show how one would go about attempting this?
Yes, that's possible. The most straightforward approach would be to zip each file individually into its own associated zip archive with one entry. When any file is modified, you replace its associated zip file to keep all of those up to date. Then you can write a simple program to take a set of those single entry zip files and merge them into a single zip file. You will need to refer to the documentation in the PKZip appnote. Take a look at that.
Now that you've read the appnote, what you need to do is use the local header, data, and central header from each individual zip file, write the local header and data as is sequentially to the new zip file, and save the central header and the offsets of the local headers in the new file. Then at the end of the new file save the current offset, write a new central directory using the central headers you saved, updating the offsets appropriately, and ending with a new end of central directory record with the offset of the start of the central directory.
Update:
I decided this was a useful enough thing to write. You can get it here.
You could zip each file before hand, and then "zip" them together with no compression at the end to quickly aggregate them into a distributable package. It won't be as efficient as compressing all the data at once, but should be faster to make modifications.
I cannot seem to locate an actual exe that implements this type of functionality. It appears that most existing tools I've tried that have the ability to merge/update will reprocess(compress) the data stream as you have already stated you saw.
However it seems what you describe can be done if you or someone wants to write it. If you take a look at this link for the ZIP file format specification, you can get an overview of the structure you would have to parse out and process. It looks like you can pretty quickly go from file to file gathering up and discarding the files of interest, then merging in your new/updated files. You would still need to rebuild a new central directory (refer to section 4.3.6 of the above linked document) within your new destination archive.
After a little more digging, the DotNetZip Library forum has a message asking about the same type of functionality which also gives a description just like I described above. It also links to this document which seems to indicate that support for that may be added to the DotNetZip library for you to further experiment with.

What's the best structure to conserve file related information?

I am building an interface whose primary function would be to act as a file renaming tool (the underlying task here is to manually classify each file within a folder according to rules that describe their content). So far, I have implemented a customized file explorer and a preview window for the files.
I now have to find a way to inform a user if a file has already been renamed (this will show up in the file explorer's listView). The program should be able to read as well as modify that state as the files are renamed. I simply do not know what method is optimal to save this kind of information, as I am not fully used to C#'s potential yet. My initial solution involved text files, but again, I do not know if there should be only one text file for all files and folders or simply a text file per folder indicating the state of its contained items.
A colleague suggested that I use an Excel spreadsheet and then simply import the row or columns corresponding to my query. I tried to find more direct data structures, but again I would feel a lot more comfortable with some outside opinion.
So, what do you think would be the best way to store this kind of data?
PS: There are many thousands of files, all of them TIFF images, located on a remote server to which I have complete access.
I'm not sure what you're asking for, but if you simply want to keep some file's information such as name, date, size etc. you could use the FileInfo class. It is marked as serializable, so that you could easily write an array of them in an xml file by invoking the serialize method of an XmlSerializer.
I am not sure I understand you question. But what I gather you want to basically store the meta-data regarding each file. If this is the case I could make two suggestions.
Store the meta-data in a simple XML file. One XML file per folder if you have multiple folders, the XML file could be a hidden file. Then your custom application can load the file if it exists when you navigate to the folder and present the data to the user.
If you are using NTFS and you know this will always be the case, you can store the meta-data for the file in a file stream. This is not a .NET stream, but a extra stream of data that can be store and moved around with each file without impacting the actual files content. The nice thin about this is that no matter where you move the file, the meta-data will move with the file, as long as it is still on NTFS
Here is more info on the file streams
http://msdn.microsoft.com/en-us/library/aa364404(VS.85).aspx
You could create an object oriented structure and then serialize the root object to a binary file or to an XML file. You could represent just about any structure this way, so you wouldn't have to struggle with the
I do not know if there should be only one text file for all files and folders or simply a text file per folder indicating the state of its contained items.
design issues. You would just have one file containing all of the metadata that you need to store. If you want speedier opening/saving and smaller size, go with binary, and if you want something that other people could open and view and potentially write their own software against, you can use XML.
There's lots of variations on how to do this, but to get you started here is one article from a quick Google:
http://www.codeproject.com/KB/cs/objserial.aspx

Securely deleting a file in C#.NET

In a project I am doing I want to give users the option of 'securely' deleting a file - as in, overwriting it with random bits or 0's. Is there an easy-ish way of doing this in C#.NET? And how effective would it be?
You could invoke sysinternals SDelete to do this for you. This uses the defragmentation API to handle all those tricky edge cases.
Using the defragmentation API, SDelete
can determine precisely which clusters
on a disk are occupied by data
belonging to compressed, sparse and
encrypted files.
If you want to repackage that logic in a more convenient form, the API is described here.
You can't securely delete a file on a journaling filesystem. The only non-journaling system still in heavy use is fat32. On any other system, the only way to securely delete is to shred the entire hard drive.
EDIT
The reason secure delete doesn't work, is that that data used to overwrite a file might not be stored in the same location as the data it is overwriting.
It seems Microsoft does provide a secure delete tool, but it does not appear to be something that you can use as a drop in replacement.
The only good way to prevent deleted file recover, short of shredding the disk, would be to encrypt the file before it is written to disk.
It wouldn't be secure at all. Instead you may wish to look at alternative solutions like encryption.
One solution would be to encrypt the contents of the data file. A new key would be used each time the file is updated. When you want to "securely delete" the data simply "lose" the encryption key and delete the file. The file will still be on the disk physically but without the encryption key recovery would be impossible.
Here is more detailed explanation as to why "secure" overwrites of files is poor security:
Without a low level tool (outside of .net runtime) you have no access to the physical disk location. Take a filestream on NTFS, when you "open a file for write access" you have no guarantee that the "updated" copy (in this case random 101010 version) will be stored in the same place (thus overwriting the original file). In fact most of the time this is what happens:
1) File x.dat is stored starting at cluster 8493489
2) You open file x.dat for write access. What is returned to you by the OS is merely a pointer to the file stream abstracted by not just the OS but the underlying file system and device drivers (hardware RAID for example) and sometimes the physical disk itself (SSD). You update the contents of the file with random 1 & 0s and close the filestream.
3) The OS likely may (and likely will) write the new file to another cluster (say cluster 4384939). It will then merely update the MFT indicating file x is now stored at 4384939.
To the end user it looks like only one copy of the file exists and it now has random data in it however the original data still exists on the disk.
Instead you should consider encrypting the contents of the file with a different key each time file is saved. When the user wants the file "deleted" delete the key and file. The physical file may remain but without encryption key recovery would be impossible.
Gutmann erasing implementation
I'd first try simply to open the file and overwrite its contents as I would normally do it. Pretty trivial in C#, I won't even bother to write it. However I don't know how secure that would be. For one thing, I'm quite certain it would not work on flash drives and SSD's that use sophisticated algorithms to provide wear leveling. I don't know what would work there, perhaps it would need to be done on driver level, perhaps it would be impossible at all. On normal drives I just don't know what Windows would do. Perhaps it would retain old data as well.

Does XDocument.Save(string filename) resave the whole file or just changes?

Basically if I do Xdoc.Load(filename), do some changes then do Xdoc.Save(filename) does it only save things that changed such as inserted or removed elements, etc, or does it resave everything?
Depending on the answer I'm thinking of determining whether my app is going to save per-change or save on explicit save and on exit. Also considering whether to write to multiple xml files or just keep everything in one big file. I have no idea how big the one big file would be but I suspect it could potentially be 10's of MBs, so if it's resaving the entire file then I definitely can't be saving every change while keeping one big file.
If it does save the entire file, does anyone have opinions of having a separate xml file for each entity (potentially hundreds) and whether or not it's a good idea?
It saves the whole file. That is the nature of text based formats. A text file cant overwrite itself without rewriting the unchanged parts.
Yes, saving a document saves the whole document.
What's the use case for the "per change" save? Is it just in case the application crashes? If so, I suggest you save these incremental changes in a temporary directory as small files, but when the user explicitly says to save the file, save it in one big file. (That's easier to copy around etc.) Delete the temporary directory on exit.
I do wonder whether you really need the temporary directory at all though. It sounds like quite a lot of work for little benefit.

Categories