• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 328
  • Last Modified:

Reading and Writing a custom Binary File

Hi guys,

I'm getting a bit bored of using databases as my data source, and for some things I find it just a bit too slow, so now I would like to create my own data file type, but I've no clue where to start...

As a starter to get me into this, I would like to make a file with a structure a bit like this:


ID
Name
DefaultState (Currently Selected State)
  StateNum (list of possible States)
  Description
  Filename
  X
  Y
    Action(list of possible Actions)
    Description
    Response
    Conditions


Since I have not done this before, I was unsure of how to type out what I wanted, but to go with the above, I will give an example, below:

[ID]=1
[Name]=Person
[DefaultState]=1
  [StateNum]=1
    [Description]=Sitting Down
    [Filename]=sitting.jpg
    [X]=452
    [Y]=95
      [Action]=Wake Up
        [NewState]=2
      [Action]=Do Nothing
        [NewState]=NULL
  [StateNum]=2
    [Description]=Standing
    [Filename]=standing.jpg
    [X]=450
    [Y]=90
      [Action]=Sit Down
        [NewState]=1
      [Action]=Do Nothing
        [NewState]=NULL



Cheers guys.
0
Cyber-Drugs
Asked:
Cyber-Drugs
  • 9
  • 8
  • 4
2 Solutions
 
2266180Commented:
well, if you want it in a binary file, then the safest way is to use some "dinamic record" pattern. for example:
record =
  int - size
  byte[] - data
end record

so what you would do is to convert all datatypes to byte[] and then write the length of byte[] and after that the data itself. this will ensure portability between platforms and programming languages and operating systems and etc.
the only drawback is that you either have to use standard converting functions (which, most datatypes have, anyway) or to define your own. this solution is not size-optimized, but it is "independent"

another way to go is to use XML. and then you can define an XSD and just use serialization (the classes can be generated from the xsd file using the xsd.exe tool from VS.) this is also independent, but it is a little bit slower and definitly has a size issue (even if you will use wbxml the size will still be an issue, since all data is converted to string)

and there are other options like making a fixed record type file. in this case you will know that (according to your example) id is exactly int size. name is exactly 50 chars long (you will have to put such constraints, otherwise it will not be fixed). etc

another way, which I never tried, is to use a streamwriter and write the data type in int. you will have to choose a wrapper that can write the common datatypes in it.
0
 
Cyber-DrugsAuthor Commented:
Hi,

Thanks for the reply, unfortunatley I don't want to go with XML, as I've also tried that way, and found that (as you mentioned above) when there is large amounts of data, the reading gets extremely slow, and sometimes just crashes the program.

I am aiming to make a custom binary file type, so platforms would not really matter, as on each platform I would just write another version of the file reading/writing functions in pure C. I know C/C++ pretty well, but never really got into files that much, appart from reading common file types...

If you could post some information, or maybe a link to a tutorial that would show me how to structure my own binary files, so that I could accomplish this goal of mine, I would highly appreciate it.

Thanks again!
0
 
gemailjCommented:
u can do it in a so easy way using binary formatter
see this article :

http://www.knowdotnet.com/articles/easybinaryserialization.html

i hope it will help u
this is the simplest way every and it is binary
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Cyber-DrugsAuthor Commented:
That looks like it may be the solution, I will try it out this evening, and let you know if it works.

Thanks!
0
 
Cyber-DrugsAuthor Commented:
Hi,

I checked out that link, and found two things...



1/  It's for Visual Basic .NET rather than C# (I know there is little difference, but since I've never used VB.NET I don't know how to convert one to another).

2/  It looks a bit confusing, especially since I've never wrote a binary file before (I've worked with Text files though).


Is it possible for it to be converted to C#, and someone to help explain how it all works to me please? From what I can tell, it looks like it's grouping data within a file, so when you access a part of the file, you access all of the data attached to it rather than a single piece at a time.


Thanks again!
0
 
gemailjCommented:
sorry for being late to response
here u r the c# translation for this solution
and it is very good solution for ur problem
plz tell me if any thing goes wrong


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace ReadingWritingCustomBinaryFile
{
    [Serializable]
    class Article : ISerializable
    {
        // any Fields
        private string author = String.Empty;
        private string text = String.Empty;
        private string title = String.Empty;

#region these 2 constructors is needed for the deserialization used by the formater
        public Article(SerializationInfo info, StreamingContext context)
        {
            Title = info.GetValue("Title", typeof(string)).ToString();
            Author = info.GetValue("Author", typeof(string)).ToString();
            Text = info.GetValue("Text", typeof(string)).ToString();
        }

        public Article()
        {
            //Empty Constructor
        }
#endregion


        public string Author
        {
            get { return author; }
            set { author = value; }
        }

        public string Text
        {
            get { return text; }
            set { text = value; }
        }

        public string Title
        {
            get { return title; }
            set { title = value; }
        }


        #region this method is needed for Serializationused by the formater
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Title", Title);
            info.AddValue("Text", Text);
            info.AddValue("Author", Author);
        }
        #endregion

        // to serialize this instance
        public void Serialize(string Filename)
        {
            Stream s = null;
            try
            {
                s = File.Open(Filename, FileMode.Create, FileAccess.ReadWrite);
                BinaryFormatter b = new BinaryFormatter();
                b.Serialize(s, this);
            }
            finally
            {
                s.Close();
            }
        }

        // to deserialize from a file and return object
        public static Article Deserialize(string Filename)
        {
            Stream s = null;
            try
            {
                s = File.Open(Filename, FileMode.Open, FileAccess.Read);
                BinaryFormatter b = new BinaryFormatter();
                return (Article)b.Deserialize(s);
            }
            finally
            {
                s.Close();
            }
        }
    }
}
0
 
Cyber-DrugsAuthor Commented:
I get loads of errors when trying to compile the code above...

Could this possibly be due to me running Visual Studio 2005 (.NET 2) and not Visual Studio 2003 (.NET 1.1) ?

If so, how could I upgrade this code to my version so there are no errors?

Cheers!
0
 
gemailjCommented:
this example is written using .NET 2.0
may be u don't use the using statments
0
 
Cyber-DrugsAuthor Commented:
I just copy and pasted the entire code into a new project to test it, and when I compile it gives me these errors:



Warning      1      The designer could not be shown for this file because none of the classes within it can be designed.  The designer inspected the following classes in the file:

      Article --- The base class 'System.Object' cannot be designed.
      Form1 --- The base class 'System.Object' cannot be designed.            0      0      
Error      2      'BinaryFile.Form1.Dispose(bool)': no suitable method found to override      C:\Documents and Settings\Justin Nel\My Documents\Visual Studio 2005\Projects\BinaryFile\BinaryFile\Form1.Designer.cs      14      33      BinaryFile
0
 
gemailjCommented:
and also has no new santics from .NET 1.1
this code may work on .NET 1.1 although it is writen in .NET 2.0 release
0
 
2266180Commented:
maybe you should save the code in a file named: Article.cs just toi make sure that that is not what the IDE is complaining about.
so create a new project, then add a new class and name it Article. then overwrite the generated code in Artile.cs with the one from here.
it should work just fine.

0
 
gemailjCommented:
all ur errors is related to the designer which mean that u try to put the code before the form1 class which allways make problems with the designer

1 - in the same project add new class file
2 - rename it to Article.cs
3 - past the code this file
4 - rename the namespace as u like

it should work now.
0
 
Cyber-DrugsAuthor Commented:
Ah it works now, I was doing it wrong, I was putting the code in Form1.cs rather than a new class!

Before I close this topic off though, could you please give a quick example of how to use this Class please?

I am guessing I would start by going:

Serialize("filename.ext");


but I'm not sure how to add/view data after that...
0
 
gemailjCommented:
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Article CurrentArticle = new Article();

        private void btnSerialize_Click(object sender, EventArgs e)
        {
            if (this.saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                SaveArticle();
                CurrentArticle.Serialize(this.saveFileDialog1.FileName);
            }
        }

        private void btnDeserialize_Click(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                CurrentArticle = Article.Deserialize(this.openFileDialog1.FileName);
                LoadArticle();
            }
        }

        private void LoadArticle()
        {
            txtAuthor.Text = CurrentArticle.Author;
            txtText.Text = CurrentArticle.Text;
            txtTitle.Text = CurrentArticle.Title;
        }

        private void SaveArticle()
        {
            CurrentArticle.Author = txtAuthor.Text;
            CurrentArticle.Text = txtText.Text;
            CurrentArticle.Title = txtTitle.Text;
        }
    }

here u r an example
i hope u enjoy it
0
 
Cyber-DrugsAuthor Commented:
Hi,

Thank you for the example, but it gives me one error when I try use it...


Error      1      'CustomFile.Article' does not contain a definition for 'Deserialize'      C:\Documents and Settings\Justin Nel\My Documents\Visual Studio 2005\Projects\CustomFile\CustomFile\Form1.cs      33      42      CustomFile




I created the two buttons, and gave them the correct names
I create the three text boxes, and gave them the correct names


What am I missing?
0
 
gemailjCommented:
the work very good and the methode is static in the Article class
see Article class line 78

// to deserialize from a file and return object
        public static Article Deserialize(string Filename)
        {
            Stream s = null;
            try
            {
                s = File.Open(Filename, FileMode.Open, FileAccess.Read);
                BinaryFormatter b = new BinaryFormatter();
                return (Article)b.Deserialize(s);
            }
            finally
            {
                s.Close();
            }
        }




check ur namespaces may it is the same namespace
in my project i have no errors
0
 
gemailjCommented:
or there is some error the Article Class
copy it again from the previous example
0
 
Cyber-DrugsAuthor Commented:
I copied it again, and double checked the names, and I still get an error:

Error      1      The type or namespace name 'Article' could not be found (are you missing a using directive or an assembly reference?)      C:\Documents and Settings\Justin Nel\My Documents\Visual Studio 2005\Projects\CustomFile\CustomFile\Form1.cs      18      17      CustomFile


Anything else it could possibly be?
0
 
2266180Commented:
well .. I didn't wanted to get into this since it was gemailj's soltuion, but since not even (s)he can see the error, maybe I should shed some light :P

so, jsut add a

using ReadingWritingCustomBinaryFile;

in the form1.cs file since Article is in namespace ReadingWritingCustomBinaryFile according to the sources above :)
0
 
Cyber-DrugsAuthor Commented:
That removed the error and it compiles and runs perfectly now!!

I only have one concern now...

After having a look at it, it looks like it stores a set amount of data, and not multiple records, like what I was after, or am I missing something?

Thanks again!
0
 
2266180Commented:
you can modify it to load/save from/to a stream instead of a file and to load/save as many records as you want.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 8
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now