Why does my binary file get rewritten each time? - c#

I'm trying to write a binary file with a dictionary of pattern objects. However, the problem I'm facing currently is that my binary file always just has one pattern object only. The previous pattern object gets rewritten by a new one whenever I add it to the dictionary.
I am not able to see how it's doing that as I serialize the entire dictionary after the data stream is created. So it should end up writing all the pattern objects to the binary file.
Here is the code snippet:
Pattern newPatternObject = new Pattern(filename, savedDistanceList, patternTangibleList);
PatternDictionary.Add(filename, newPatternObject);
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("Pattern.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, PatternDictionary);
stream.Close();
Any help will be much appreciated. Thank you.

Change your FileMode.Create to FileMode.Append

Related

Can I send an obj of a class to a file using filestream in C#?

I was wondering if I can send a whole obj which has 4 members:
string name
string lastname
int StudentID
int CitizenID
using the filestream commends to save in a .txt file in binary format?
I know of Serialization, and it sends an obj to a .xml file quite easily, but when I made my program using it and showed it to my teacher, he said he don't want me to use it, said I have to use the base filestream commands like fstream, instream, outstream and ... in C++ , and told me he want a binary format saved .txt file.
Now my question is, can I send a whole obj to a .txt file in C# or do i have to send it like a string, which will be quite a lot of work.
Because I have to turn all members to string then put a indicator or something at end of each so I can read from them later and separate them.
now my question is , can i send a whole obj to a .txt file in C# or do i have to send it like a string ... which will be quite a lot of work ,
Yes, there is a name for this: serialization. Whether you do it manually in your own code, or using one of a range of existing serialization libraries, it is serialization. If your teacher doesn't want you using a serialization library, then you would have to do it in your own code. Which is frankly stupid. I wonder if the teacher wants you to write raw commands to the hard disk as well, to avoid all those silly abstractions like a HAL, OS, or common class libraries...
It may be worth clarifying with your teacher exactly what is, and is not, acceptable. For example, would a binary serializer suffice? I could name several. Would it be OK to use BinaryWriter / BinaryReader? Or is the intent of the exercise to make you think about what you need to do to serialize/deserialize? If the latter: then yes, learn about streams, encodings, and framing protocols (sentinel-values vs length-prefixed data, etc).
I'd use this...
void saveInBinary()
{
IFormatter binaryFormatter = new BinaryFormatter();
Stream binaryStream = new FileStream("File Path Here", FileMode.Create, FileAccess.Write, FileShare.None);
binaryFormatter.Serialize(binaryStream, this);
binaryStream.Close();
}
Stick that in the object's member space, and just call it.
Or, something a bit more useful...
void saveInBinary(object o)
{
IFormatter binaryFormatter = new BinaryFormatter();
Stream binaryStream = new FileStream("File Path Here", FileMode.Create, FileAccess.Write, FileShare.None);
binaryFormatter.Serialize(binaryStream, o);
binaryStream.Close();
}
This will serialize any object passed to it.
Last variation (I promise!) :p
void saveInBinary(object o, string filePath)
{
IFormatter binaryFormatter = new BinaryFormatter();
Stream binaryStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
binaryFormatter.Serialize(binaryStream, o);
binaryStream.Close();
}
This one allows you to pass an object and a filepath to the method to serialize the passed object to the passed filepath.
Of course, this will not allow you to read the contents of the .txt file. It'll look like mumbo jumbo. If your intent is to write the data to a human readable file, well, there are tons of examples for that. :p I just provided the serialization stuff because it took me a while to figure it out. ;)
Edit: Shoot. I forgot some code...
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
Code needs those to work (for the IFormatter) Also, for Stream to work, you need to use
using System.IO;
Sorry for forgetting.
Edit 2: Forgot to mention, you'll need to use the [Serializeable] tag on the object(s) you wish to serialize this way. Just put "[Serializeable]" on top of the class you want to serialize.
[Serializeable]
class SerializeableObject
{
string aString;
void aMethod()
{
}
}
Like so.

(De)Serializing multiple items to file

I want to serialize/deserialize multiple object from/to a file. The syntax should be similar to this:
obj.Append(byteArray);
obj.Append(byteArray);
obj.Append(byteArray);
IEnumerable<byte[]> obj.Extract();
While this is very simple to accomplish (e.g., write a class that uses a filestream and protobuf-net internally), I'm wondering if there is any more elegant way of doing this. Is there any class (from a third party library), that uses a serializer to write to an filestream?
Edit: I need this as a filestream that captures video data that is sent through network. So the filestream must be open for a dedicated amount of time. My previous solution was to save every video frame to a new file, but it's not scalable (especially for hdd, and increasing video partners).
What about:
using(var stream = File.Open(filename, FileMode.Create))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, firstObjectToSerialize);
formatter.Serialize(stream, secondObjectToSerialize);
}

Deserialize on the fly, or LINQ to XML

Working with C# Visual Studio 2008, MVC1.
I'm creating an xml file by fetching one from a WebService and adding some nodes to it. Now I wanted to deserialize it to a class which is the model used to strongtyped the View.
First of all, I'm facing problems to achieve that without storing the xml in the filesystem cause I don't know how this serialize and deserialize work. I guess there's a way and it's a matter of time.
But, searching for the previous in the web I came accross LINQ to XML and now I doubt whether is better to use it.
The xml would be formed by some clients details, and basically I will use all of them.
Any hint?
Thanks!!
You can save a XElement to and from a MemoryStream (no need to save it to a file stream)
MemoryStream ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms);
document.Save(xw);
xw.Flush();
Then if you reset the position back to 0 you can deserialize it using the DataContractSerializer.
ms.Position = 0;
DataContractSerializer serializer = new DataContractSerializer(typeof(Model));
Model model = (model) serializer.ReadObject(ms);
There are other options for how serialization works, so if this is not what you have, let me know what you are using and I will help.
try this:
XmlSerializer xmls = new XmlSerializer(typeof(XElement));
FileStream FStream;
try
{
FStream = new FileStream(doctorsPath, FileMode.Open);
_Doctors = (XElement)xmls.Deserialize(FStream); FStream.Close();
FStream = new FileStream(patientsPath, FileMode.Open);
_Patients = (XElement)xmls.Deserialize(FStream)
FStream.Close();
FStream = new FileStream(treatmentsPath, FileMode.Open);
_Treatments = (XElement)xmls.Deserialize(FStream);
FStream.Close();
}
catch
{ }
This will load all of the XML files into our XElement variables. The try – catch block is a form of exception handling that ensures that if one of the functions in the try block throws an exception, the program will jump to the catch section where nothing will happen. When working with files, especially reading files, it is a good idea to work with try – catch.
LINQ to XML is an excellent feature. You can always rely on that. You don't need to write or read or data from file. You can specify either string or stream to the XDocument
There are enough ways to load an XML element to the XDocument object. See the appropriate Load functions. Once you load the content, you can easily add/remove the elements and later you can save to disk if you want.

XmlWriter in non locking mode

I wanna to have the ability to write an XML file with XmlTextWriter or LINQ to XML but by the way I don't want the file to be locked completely. I wanna the other processes to be able to read the Xml file. It should be locked only in write mode so that the others may not modify the file.
What is the best way to achieve this ?
You need to set this when you open the FileStream. Try this:
var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
var xmlWriter = XmlWriter.Create(fs);
As Yahia mentions, there is no guarantee that the data written at any point will be meaningful to a reader.

Reading / Writing text file repeatedly / simultaneously

How do I read and write on a text file without getting the exception that "File is already in use by another app"??
I tried File.readalltext() and File.Appendalltext() functions..I'm just starting out with filestream.
Which would work out best in my scenario? I would appreciate some code snipplets too ..
Thanks
This is all to do with the lock and sharing semantics that you request when opening the file.
Instead of using the shortcut approach of File.ReadAllText(), try looking into using a System.IO.FileStream and a System.IO.StreamReader / System.IO.StreamWriter.
To open a file:
using (var fileStream = new FileStream(#"c:\myFile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamReader = new StreamReader(fileStream))
{
var someText = streamReader.ReadToEnd();
}
Note the FileShare.ReadWrite - this is telling the stream to allow sharing to either other readers or other writers.
For writing try something like
using (var fileStream = new FileStream(#"c:\myFile", FileMode.Create, FileAccess.Write, FileShare.Read))
using (var streamWriter = new StreamWriter(fileStream))
{
streamWriter.WriteLine("some text");
}
Note the FileShare.Read - this is telling the stream to allow sharing to readers only.
Have a read around the System.IO.FileStream and its constructor overloads and you can tailor exactly how it behaves to suit your purpose.
You need to make sure the file is not being used by any other application.
With your own application, you cannot read from a file multiple times without closing the stream between reads.
You need to find out why the file is in use - a tool like FileMon can help finding out.

Categories