none
Reading Binary Format (QBasic) with C#

    Question

  • I have a binary file with data stored in an old format [Microsoft Binary Format (QBasic)]

    The file is configured like this

    -----------------------------------------------------
    Start Byte | End Byte | Lenght | Description        |
    -----------------------------------------------------
        0    |     3    |   4    | date format YYMMDD |
    -----------------------------------------------------
        4    |     7    |   4    | Float              |
    -----------------------------------------------------
        8    |     11   |   4    | Float              |
    -----------------------------------------------------
      \
      \
      \
    -----------------------------------------------------
       24    |     27   |   4    | Float              |
    ----------------------------------------------------- 

    The first 4 bytes contain the date and reset all in Float like 34.5

    When i read the file using BinaryRead i do not know to convert to date and float

    Here is my code
    ========================================================


            FileStream fs;
            BinaryReader br;

            byte[] buffer = new byte[28];
            int intBuffer = 0;

    fs = File.Open("myFile.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    br = new BinaryReader(fs);

                while ((intBuffer = br.Read(buffer, 0, 28)) > 0)
                {
                    DateTime date = GetDateOutOfByte(buffer, 0, 3);
                    float f1 = GetFloatOutOfByte(buffer, 4, 7);
                    float f2 = GetFloatOutOfByte(buffer, 8, 11);
                    float f3 = GetFloatOutOfByte(buffer, 12, 15);
                    float f4 = GetFloatOutOfByte(buffer, 16, 19);
                    float f5 = GetFloatOutOfByte(buffer, 20, 23);
                    float f6 = GetFloatOutOfByte(buffer, 24, 27);
                }

    -----------------------------
    private float GetFloatOutOfByte(byte[] buffer, int Start, int End)
            {
                string temp = "";
                float result =0.0F;
                for (int i = Start; i < End; i++)
                {
                    temp += (char)bufferIdea;
                }
                // How to convert the temp to float?

                return result;
            }
    ------------------------------
    private DateTime GetDateOutOfByte(byte[] buffer, int Start, int End)
            {
                string temp = "";
                DateTime result;
                for (int i = Start; i < End; i++)
                {
                    temp += (char)bufferIdea;
                }
                // How to convert the temp to Date?

                return result;
            }
    ------------------------------

    Any Help Please


     

    Wednesday, July 12, 2006 10:19 PM

Answers

  • The System.BitConverter provides methods which let you convert a byte buffer's content to various 'core' value types.

    Since the byte representation of System.Single (float) is fixed at 4 bytes, there is no need of the End parameter of the helper function.

    For the Date field - is its data stored in text in the format YYMMDD or is it the number of seconds since 1/1/1970?

    In either case the length of the date representation is fixed.

    This is what the code should look like:

    FileStream fs;
    BinaryReader br;

    byte[] buffer = new byte[28];
    int intBuffer = 0;

    fs = File.Open("myFile.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    br = new BinaryReader(fs);

    while ((intBuffer = br.Read(buffer, 0, 28)) > 0)
    {
     DateTime date = GetDateOutOfByte(buffer, 0);
     float f1 = GetFloatOutOfByte(buffer, 4);
     float f2 = GetFloatOutOfByte(buffer, 8);
     float f3 = GetFloatOutOfByte(buffer, 12);
     float f4 = GetFloatOutOfByte(buffer, 16);
     float f5 = GetFloatOutOfByte(buffer, 20);
     float f6 = GetFloatOutOfByte(buffer, 24);
    }

    // ...

    private float GetFloatOutOfByte(byte[] buffer, int Start)
    {
     return BitConverter.ToSingle(buffer, Start);
    }

    // If date is represented in seconds in file, include this function:

    private DateTime GetDateOutOfByte(byte[] buffer, int Start)
    {
     int iSecs = BitConverter.ToInt32(buffer, Start);
     return new DateTime(1970, 1, 1).AddSeconds(iSecs);
    }

    // Otherwise, this one will read the textual data:

    private DateTime GetDateOutOfByte(byte[] buffer, int Start)
    {
     string yy = BitConverter.ToString(buffer, Start, 2);
     string mm = BitConverter.ToString(buffer, Start + 2, 2);
     string dd = BitConverter.ToString(buffer, Start + 4, 2);

     return new Date((yy < 70 ? 2000 : 1900) + yy, mm, dd);
    }

    Wednesday, July 12, 2006 10:56 PM

All replies

  • The System.BitConverter provides methods which let you convert a byte buffer's content to various 'core' value types.

    Since the byte representation of System.Single (float) is fixed at 4 bytes, there is no need of the End parameter of the helper function.

    For the Date field - is its data stored in text in the format YYMMDD or is it the number of seconds since 1/1/1970?

    In either case the length of the date representation is fixed.

    This is what the code should look like:

    FileStream fs;
    BinaryReader br;

    byte[] buffer = new byte[28];
    int intBuffer = 0;

    fs = File.Open("myFile.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    br = new BinaryReader(fs);

    while ((intBuffer = br.Read(buffer, 0, 28)) > 0)
    {
     DateTime date = GetDateOutOfByte(buffer, 0);
     float f1 = GetFloatOutOfByte(buffer, 4);
     float f2 = GetFloatOutOfByte(buffer, 8);
     float f3 = GetFloatOutOfByte(buffer, 12);
     float f4 = GetFloatOutOfByte(buffer, 16);
     float f5 = GetFloatOutOfByte(buffer, 20);
     float f6 = GetFloatOutOfByte(buffer, 24);
    }

    // ...

    private float GetFloatOutOfByte(byte[] buffer, int Start)
    {
     return BitConverter.ToSingle(buffer, Start);
    }

    // If date is represented in seconds in file, include this function:

    private DateTime GetDateOutOfByte(byte[] buffer, int Start)
    {
     int iSecs = BitConverter.ToInt32(buffer, Start);
     return new DateTime(1970, 1, 1).AddSeconds(iSecs);
    }

    // Otherwise, this one will read the textual data:

    private DateTime GetDateOutOfByte(byte[] buffer, int Start)
    {
     string yy = BitConverter.ToString(buffer, Start, 2);
     string mm = BitConverter.ToString(buffer, Start + 2, 2);
     string dd = BitConverter.ToString(buffer, Start + 4, 2);

     return new Date((yy < 70 ? 2000 : 1900) + yy, mm, dd);
    }

    Wednesday, July 12, 2006 10:56 PM
  • Stanimir S Stoyanov  >>>>> Thanks for you help

    I have tried the code you have changed and here is my feedback

    =========================================================

    for this method

    private float GetFloatOutOfByte(byte[] buffer, int Start)
            {
                return BitConverter.ToSingle(buffer, Start);

            }

    I get float like this


    -4.513898E-35
    -9.930576E-35
    -1.090859E-34

    which is wrong becase i expect numbers like these 156.5  or 150.75  or 54.25

    ==================================================================
    for this method
           private DateTime GetDateOutOfByte(byte[] buffer, int Start)
            {
                int iSecs = BitConverter.ToInt32(buffer, Start);
                return new DateTime(1970, 1, 1).AddSeconds(iSecs);
            }


    I get date like this

    5/16/1908 9:41:20 PM
    9/6/1905 3:56:48 AM

    Which is wrong because i knew what should get ( Some thing like this 7/12/2006 6:30PM or 7/12/2006 10:00AM)
    in this year 2006
    ==================================================================

    for this method did not work
     
     private DateTime GetDateOutOfByte(byte[] buffer, int Start)
            {
                string yy = BitConverter.ToString(buffer, Start, 2);
                string mm = BitConverter.ToString(buffer, Start + 2, 2);
                string dd = BitConverter.ToString(buffer, Start + 4, 2);

                return new Date((yy < 70 ? 2000 : 1900) + yy, mm, dd);
            }

    I get this error

    Error 1 The type or namespace name 'Date' could not be found (are you missing a using directive or an assembly reference?) D:\MyApplications\ReadingBinaryFile\Form1.cs 60 24 ReadingMetaStockFile
    Error 2 Operator '<' cannot be applied to operands of type 'string' and 'int' D:\MyApplications\ReadingBinaryFile\Form1.cs 60 30 ReadingMetaStockFile
    ==================================================================

    Thursday, July 13, 2006 9:53 AM
  • Could you please post a sample QBasic file so that we can make the necessary changes to the code?
    Thursday, July 13, 2006 9:56 AM
  •  Stanimir S Stoyanov wrote:
    Could you please post a sample QBasic file so that we can make the necessary changes to the code?

     

    Here is  a real file that i am using

    download it from here

    http://www.freefilespace.net/index.php?id=1148

    Note:

    1. Use WinZip to open the file

    2. Ignore the first 28 byte in Binary File since they are header ( From 0 to 27)

    br.Position = 28;  (or 27 i am not sure)

     

    Thanks

    Thursday, July 13, 2006 1:59 PM
  •  daydreamsy2k wrote:

     Stanimir S Stoyanov wrote:
    Could you please post a sample QBasic file so that we can make the necessary changes to the code?

     

    Here is  a real file that i am using

    download it from here

    http://www.freefilespace.net/index.php?id=1148

    Note:

    1. Use WinZip to open the file

    2. Ignore the first 28 byte in Binary File since they are header ( From 0 to 27)

    br.Position = 28;  (or 27 i am not sure)

     

    Thanks

    =====================================

    The first record is header and each record is 28 Bytes
    The first 4 bytes of the first record contain the number of records in the file.

    *** The first record is an header

    ============================================

    Thursday, July 13, 2006 2:13 PM
  •  

    Here is a C or C++ (I do not know)  method >>> Can any body convert it to C#

    ==================================================

    /* IEEE floating point format to Microsoft Basic floating point format */
    typedef unsigned short u_short;
    typedef unsigned long u_long;

    int fieee2msbin(float *src, float *dst)
    {
        union
     {
      float a;
      u_long b;
        } c;


        u_short man;
        u_short exp;


        c.a = *src;
        if (c.b)
     {  /* not zero */
      man = c.b >> 16;
      exp = ((man << 1) & 0xff00) + 0x0200;
      if (exp & 0x8000 != (man << 1) & 0x8000)
       return 1; /* exponent overflow */
      man = man & 0x7f | (man >> 8) & 0x80; /* move sign */
      man |= exp;
      c.b = c.b & 0xffff | (long)man << 16;
        }
        *dst = c.a;
        return 0;

     

    }


    /* Microsoft Basic floating point format to IEEE floating point format */
    int fmsbin2ieee(float *src, float *dst)
    {
        union
     {
      float a;
      u_long b;
        } c;

        u_short man;
        u_short exp;


        c.a = *src;
        if (c.b)
     {  /* not zero */
      man = c.b >> 16;
      exp = (man & 0xff00) - 0x0200;
      if (exp & 0x8000 != man & 0x8000)
       return 1; /* exponent overflow */
      man = man & 0x7f | (man << 8) & 0x8000; /* move sign */
      man |= exp >> 1;
      c.b = c.b & 0xffff | (long)man << 16;
        }
        *dst = c.a;
        return 0;

     

    }

    Friday, July 14, 2006 10:48 AM
  • The C# equivalents of the above functions are below. A quick test of the type:

    float src = 34.5f;
    float dst = fmsbin2ieee(src);
    float res = fieee2msbin(dst);

    shows that they work fine, but still the QBasic file returns odd values.

    // Microsoft Basic floating point format to IEEE floating point format

    private static float fmsbin2ieee(float src)
    {

     uint bin = BitConverter.ToUInt32(BitConverter.GetBytes(src), 0);

     uint man;
     uint exp;

     if (bin != 0)
     {  /* not zero */
      man = bin >> 16;
      exp = (man & 0xff00) - 0x0200;

      if ((exp & 0x8000) != (man & 0x8000))
       throw new OverflowException(); /* exponent overflow */

      man = man & 0x7f | (man << 8) & 0x8000; /* move sign */
      man |= exp >> 1;
      bin = bin & 0xffff | man << 16;
     }

     return BitConverter.ToSingle(BitConverter.GetBytes(bin), 0);
    }

    // IEEE floating point format to Microsoft Basic floating point format

    private static float fieee2msbin(float src)
    {
     uint b = BitConverter.ToUInt32(BitConverter.GetBytes(src), 0);

     uint man;
     uint exp;

     if (b != 0)
     {  /* not zero */
      man = b >> 16;
      exp = ((man << 1) & 0xff00) + 0x0200;

      if ((exp & 0x8000) != ((man << 1) & 0x8000))
       throw new OverflowException(); /* exponent overflow */

      man = man & 0x7f | (man >> 8) & 0x80; /* move sign */
      man |= exp;
      b = b & 0xffff | man << 16;
     }

     return BitConverter.ToSingle(BitConverter.GetBytes(b), 0);
    }

    Based on these functions, I modified GetFloatOutOfByte to:

    private static float GetFloatOutOfByte(byte[] buffer, int Start)
    {
     return fieee2msbin(BitConverter.ToSingle(buffer, Start));
    }
    Friday, July 14, 2006 12:47 PM
  • I have tried it but still can get it work

    Would you please look at this complete program writen in C++ and get some thing out of it ( Sorry I do not know any thing in C++ it is very difficalt )

     

    ====================================

    Yamamoto
     Mar 26 1999, 11:00 am   show options

    Newsgroups: misc.invest.technical
    From: "Yamamoto" <xellio...@hotmail.com> - Find messages by this author 
    Date: 1999/03/26
    Subject: Re: META data format
    Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse 

    'The QuickBasic program that follows can be used to READ
    prices from EOD Metastock data files
    (7 fields: D O H L C V OI):


    Drive$="C:"             ' drive where data file is located
    Path$="\DATA\"          ' path where data files is located
    FileName$="F1.DAT"      ' name of the file to read
    Open "R",#1,Drive$+Path$+FileName$,28
    Field #1,28 as AX$: Get 1,1:NumRec=CVI(MID$(AX$,3))
    Field #1,4 as DX$,4 as OX$,4 as HX$,4 as LX$,4 as CX$,4 as VX$,4 as OIX$
    N=NumRec
    DIM Date(N),Opn(N),High(N),Low(N),Clse(N),Volume(N),OpInt(N)
    for i=2 to NumRec
            Get 1,i
            Date(i)=cvsmbf(DX$):Opn(i)=cvsmbf(OX$)
            High(i)=cvsmbf(HX$):Low(i)=cvsmbf(LX$)
            Clse(i)=cvsmbf(CX$):Volume(i)=cvsmbf(VX$)
            OpInt(i)=cvsmbf(OIX$)
    next i
    end


    or this one unknown language to me :


    typedef unsigned char u_char;
    typedef unsigned short u_short;


    /*
     * MASTER file description
     *  floats are in Microsoft Basic format
     *  strings are padded with spaces, not null terminated
     */
    struct rec_1
    {
        u_short num_files;     /* number of files master contains */
        u_short file_num;     /* next file number to use (highest F# used) */
        char zeroes[49];

     

    };


    struct rec_2to255   /* description of data files */
    {
        u_char file_num;     /* file #, i.e., F# */
        char file_type[2];     /* CT file type = 0'e' (5 or 7 flds) */
        u_char rec_len;   /* record length in bytes (4 x
    num_fields) */
        u_char num_fields;     /* number of 4-byte fields in each record */
        char reserved1[2];     /*  in the data file */
        char issue_name[16];    /* stock name */
        char reserved2;
        char CT_v2_8_flag;     /* if CT ver. 2.8, 'Y'; o.w., anything else */
        float first_date;     /* yymmdd */
        float last_date;
        char time_frame;     /* data format: 'I'(IDA)/'W'/'Q'/'D'/'M'/'Y' */
        u_short ida_time;     /* intraday (IDA) time base */
        char symbol[14];     /* stock symbol */
        char reserved3;   /* MetaStock reserved2: must be a space
    */
        char flag;    /* ' ' or '*' for autorun */
        char reserved4;


    };


    /*
     * EMASTER data structure
     *  floats are in IEEE format
     *  strings are padded with nulls
     */
    struct emashdr
    {
        u_short num_files;     /* number of files in emaster */
        u_short file_num;     /* last (highest) file number */
        char stuff[188];


    };


    struct emasdat
    {
        char asc30[2];   /* "30" */
        u_char file_num;     /* file number F# */
        char fill1[3];
        u_char num_fields;     /* number of 4-byte data fields */
        char fill2[2];
        char flag;    /* ' ' or '*' for autorun */
        char fill3;
        char symbol[14];     /* stock symbol */
        char fill4[7];
        char issue_name[16];    /* stock name */
        char fill5[12];
        char time_frame;     /* data format: 'D'/'W'/'M'/ etc. */
        char fill6[3];
        float first_date;     /* yymmdd */
        char fill7[4];
        float last_date;
        char fill8[116];


    };


    /* seven-field data file description */
    struct dathdr7
    {
        u_short max_recs;     /* 0 ==> unlimited size */
        u_short last_rec;     /* dathdr7 = 1; ctdata7 starts with 2 */
        char zeroes[24];


    };


    struct ctdata7
    {
        float date;
        float open;
        float high;
        float low;
        float close;
        float volume;
        float op_int;


    };


    /* five-field data file description */
    struct dathdr5
    {
        u_short max_recs;
        u_short last_rec;
        char zeroes[16];


    };


    struct ctdata5
    {
        float date;
        float high;
        float low;
        float close;
        float volume;


    };


    /* IEEE floating point format to Microsoft Basic floating point format */
    typedef unsigned short u_short;
    typedef unsigned long u_long;

    int fieee2msbin(float *src, float *dst)
    {
        union
     {
      float a;
      u_long b;
        } c;


        u_short man;
        u_short exp;


        c.a = *src;
        if (c.b)
     {  /* not zero */
     
    man = c.b >> 16;
      exp = ((man << 1) & 0xff00) + 0x0200;
      if (exp & 0x8000 != (man << 1) & 0x8000)
       return 1; /* exponent overflow */
      man = man & 0x7f | (man >> 8) & 0x80; /* move sign */
      man |= exp;
      c.b = c.b & 0xffff | (long)man << 16;
        }
        *dst = c.a;
        return 0;

     

    }


    /* Microsoft Basic floating point format to IEEE floating point format */
    int fmsbin2ieee(float *src, float *dst)
    {
        union
     {
      float a;
      u_long b;
        } c;

        u_short man;
        u_short exp;


        c.a = *src;
        if (c.b)
     {  /* not zero */
      man = c.b >> 16;
      exp = (man & 0xff00) - 0x0200;
      if (exp & 0x8000 != man & 0x8000)
       return 1; /* exponent overflow */
      man = man & 0x7f | (man << 8) & 0x8000; /* move sign */
      man |= exp >> 1;
      c.b = c.b & 0xffff | (long)man << 16;
        }
        *dst = c.a;
        return 0;

     

    }
    ========================================================

    Friday, July 14, 2006 1:16 PM
  • Thank you for posting this. Apparently, the floating point numbers are encoded in Microsoft's old Binary Format. The GetFloatOutOfByte function becomes

      private static float GetFloatOutOfByte(byte[] buffer, int Start)
      {
       byte[] msbin = new byte[4];
       byte[] ieee = new byte[4];
       byte sign = 0x00;
       byte ieee_exp = 0x00;

       Buffer.BlockCopy(buffer, Start, msbin, 0, 4);

       sign = (byte)(msbin[2] & 0x80);
       /* any msbin w/ exponent of zero = zero */
       if (msbin[3] == 0) return 0;
       ieee[3] |= sign;
       ieee_exp = (byte)(msbin[3] - 2);
       ieee[3] |= (byte)(ieee_exp >> 1);
       ieee[2] |= (byte)(ieee_exp << 7);
       ieee[2] |= (byte)(msbin[2] & 0x7f);
       ieee[1] = msbin[1];
       ieee[0] = msbin[0];
       return BitConverter.ToSingle(ieee, 0);
      }

    This function returns sensible values such as 7913.0, 1815.0, etc. According to the posted application, the Date is also encoded in this format. Do you reckon what '1060206' would mean for Date, and exactly what date value is expected for the posted file (F50)?

    Friday, July 14, 2006 1:39 PM
  • I think you almost get it

    First of all you get the decimal places correctly like xx.25 or xx.50 or xx.75 which is correct but for the xx the expected values are

    from 126  to 186 for F50.dat  ( it could be 126 or 126.25 or 126.75 ....... or 168 or 168.25 or 168.75

    and date

    from 5/16/2006   to   7/12/2006

    Thanks

    Friday, July 14, 2006 1:56 PM
  • Please take a look to what (alanfo) from [GotDotNet.com] did

    ========================================

    However, I believe Stanimir has cracked the conversion to IEEE from first principles using pure C#. I've tested his method and it gives the same answers as the corresponding function in the dll.

    I see that the date has also been encoded as an MBF float and it remains to decide what base date has been used for the year. My guess now would be 1900 and so today would correspond to an MBF float of 1060714.

    Assuming that's correct, I've added 3 more methods to the MBFConverter class:

       // date to be passed in format "YYMMDD" or, if after 1999, "YYYMMDD"

       public static float EncodeDateToMBF (string date)
       {
        return Convert.ToSingle(date);
       }

      // MBFDate is a date encoded as an MBF float

       public static string DecodeDateFromMBF (float MBFDate)
       {
        string date = MBFDate.ToString();
        int len = date.Length;
        string day = date.Substring(len-2);
        string month = date.Substring(len-4,2);  
        string year = (int.Parse(date.Substring(0,len-4)) + 1900).ToString();
        return month +"/" + day + "/" + year;
       }
     
       // IEEEDate is the IEEE float equivalent of a date encoded as an MBF float

       public static string DecodeDateFromIEEE (float IEEEDate)
       {    
        return DecodeDateFromMBF(MBFConverter.ToMBF(IEEEDate));
       }  

    -Alan


     

    Saturday, July 15, 2006 4:17 AM
  • Work 100% Is it possible to convert it to C#

    === Coded by Gianluca Scacco ==========

    ========================================
    // This is for the date
    GetBufferDateLong(buff2, 0, 3)
    ========================================

    Private Function GetBufferDateLong(ByVal Buffer() As Byte, ByVal B As Integer, ByVal E As Integer) As Date
            Dim s As Single
            Dim res As Date
            Dim sstring As String
            Dim YY As Integer
            Dim MM As Integer
            Dim DD As Integer

            s = GetBufferMBF(Buffer, B, E)
            sstring = s
            If sstring.Substring(0, 1) = "1" Then
                YY = sstring.Substring(1, 2)
                MM = sstring.Substring(3, 2)
                DD = sstring.Substring(5, 2)
            Else
                YY = sstring.Substring(0, 2)
                MM = sstring.Substring(2, 2)
                DD = sstring.Substring(4, 2)
            End If
            res = DateSerial(YY, MM, DD)
            Return res
        End Function


    ========================================
    // This is for the float
    GetBufferMBF(buff2, 4, 7) 
    ========================================
    Private Function GetBufferMBF(ByVal Buffer() As Byte, ByVal B As Integer, ByVal E As Integer) As Single
            If B > Buffer.GetLength(0) OrElse E > Buffer.GetLength(0) Then
                Throw New Exception("String out of range")
                Exit Function
            End If
            Dim str As String
            For i As Integer = B To E
                str &= Chr(Buffer(i))
            Next
            Return CVSMBF(str)
        End Function


    Shared Function CVSMBF(ByVal Num As String) As Single
            Dim Expon As Integer
            Dim Mant As Integer
            Dim NSign As Integer
            Dim Result As Single
            Result = 0
            If Len(Num) = 4 Then
                Expon = Asc(Right$(Num, 1)) - 128
                Mant = Asc(Mid$(Num, 3, 1))
                NSign = Mant \ 128
                Mant = 128 + Mant Mod 128
                Result = Mant / 256 + Asc(Mid$(Num, 2, 1)) / 256 ^ 2 _
                         + Asc(Left$(Num, 1)) / 256 ^ 3
                Result = Result * 2 ^ Expon
                If NSign Then
                    Result = -Result
                End If
            End If
            Return Result
        End Function
    =======================================================

    Saturday, July 15, 2006 4:41 AM
  • Following are the conversions. I tested the VB code and the same values (100000.0, 1815.0, etc) are read, too. Are you sure about the values? Apparently, the MBF->IEEE conversion is done correctly, according to various sources, including http://support.microsoft.com/kb/q140520/.


     FileStream fs;
     BinaryReader br;

     byte[] buffer = new byte[28];
     int intBuffer = 0;

     fs = File.Open("myFile.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
     br = new BinaryReader(fs);
     br.BaseStream.Position = 28;
     while ((intBuffer = br.Read(buffer, 0, 28)) > 0)
     {
      DateTime dt = DecodeDateFromMBF(GetBufferMBF(buffer, 0, 3));
      float f1 = GetBufferMBF(buffer, 4, 7);
      float f2 = GetBufferMBF(buffer, 8, 11);
      float f3 = GetBufferMBF(buffer, 12, 15);
      float f4 = GetBufferMBF(buffer, 16, 19);
      float f5 = GetBufferMBF(buffer, 20, 23);
      float f6 = GetBufferMBF(buffer, 24, 27);
     }

    //
    // This is for the date
    // GetBufferDateLong(buff2, 0)
    //
    public static DateTime DecodeDateFromMBF(float MBFDate)
    {
     string date = MBFDate.ToString();
     int len = date.Length;
     int day = int.Parse(date.Substring(len - 2));
     int month = int.Parse(date.Substring(len - 4, 2));
     int year = int.Parse(date.Substring(0, len - 4)) + 1900;
     return new DateTime(year, month, day);
    }

    public static float GetBufferMBF(byte[] buffer, int Start, int End)
    {
     if (Start > buffer.Length || End > buffer.Length)
      throw new ArgumentOutOfRangeException("Start");

     string str = string.Empty;
     for (int i = Start; i <= End; i++)
      str += (char)buffer[ i ];

     return CvsMbf(str);
    }

    public static float CvsMbf(string num)
    {
     int exp, man, nSign;
     float res = 0;

     if (num.Length == 4)
     {
      exp = num[3] - 128;
      man = num[2];
      nSign = man / 128;
      man = 128 + man % 128;
      res = (float)
       (man / 256f + num[1] / Math.Pow(256, 2)
       + num[0] / Math.Pow(256, 3));
      res = res * (float)Math.Pow(2f, exp);
      if (nSign == 1)
       res = -res;
     }
     return res;
    }

    • Proposed as answer by GL88 Thursday, November 5, 2009 12:23 PM
    Saturday, July 15, 2006 11:30 AM
  •  

    I am 100% sure that

    decimal places  like xx.25 or xx.50 or xx.75 ( Nothing  like xx.98 or xx.63)

    it is always .00 or .25 or .50  or .75

     

    xx the expected values are

    from 126  to 186 for F50.dat  ( it could be 126 or 126.25 or 126.75 ....... or 168 or 168.25 or 168.75

    and date

    from 5/16/2006   to   7/12/2006

     

    Saturday, July 15, 2006 12:09 PM
  • Hello,

    Did this issue ever get resolved? I would like to know how to read and write to this same file format.
    Thursday, August 7, 2008 4:53 AM
  • Great Post sir,Thanks a lot for this. its working charm while reading .dat files.

    Sir can you help me to read Metastock file which includes Master,Emaster& Xmaster. This contans info about symbol and F* info and so on. i wil be your obligator

    I tried alot by googles but i didn't find. if you help for Master and link to child(F*) to read  then will do for remainig like Emaster and Xmastre.

    Please Help me.

    Thursday, January 30, 2014 4:14 AM