Question

I am C# beginner and trying to read a binary file to calculate the frequency of the symbols inside the binary file. (Frequency is the number of time the symbols repeats).

As first step I kept the data type of "symbol" read as "int" and code worked fine. But now I wanted to make this symbol of generic type (I mean <T> type).

The code compiles with out any error in Ubuntu terminal.

But when I execute using "mono filename.exe BinaryFile.bin" This binary file is read at sole argument. Please see at last that how i got this Binary file BinaryFile.bin

The error is : (I know the cause of this error, I have mentioned below but don't know the soultion.)

   hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$ mono cbk.exe  toto.bin 

Unhandled Exception: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
  at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0 
  at Final.A`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0 
  at Final.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
  at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0 
  at Final.A`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0 
  at Final.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0 
hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$ 

My equivalent of full code to do so is (narrowed code, it do the same you can compile it if you want):

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Final 
{
    public class A <T> where T: struct, IComparable <T> , IEquatable <T> 
    {
        public class Node 
        {
            public T symbol;
            public Node next;
            public int freq;
        }

        public Node Front;

        public A(string[] args, Func <byte[], int, T> converter) 
        {    
            int size = Marshal.SizeOf(typeof (T));
            Front = null;
            using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0]))) 
            {   
                while (stream.BaseStream.Position < stream.BaseStream.Length) 
                {   
                    byte[] bytes = stream.ReadBytes(size);   
                    T processingValue = converter(bytes, 0);  

                    Node pt, temp;
                    pt = Front;

                    while (pt != null) 
                    {   Console.WriteLine("check1");
                        if (pt.symbol.Equals(processingValue)) 
                        {
                            pt.freq++;
                            break;
                        }
                        Console.WriteLine("Symbol : {0}  frequency is : {1}", pt.symbol, pt.freq);
                        temp = pt;
                        pt = pt.next;
                    }
                }
            }
        }
    }

    public class MyClass 
    {
        public static void Main(string[] args) 
        {
            A <long> ObjSym = new A <long> (args, BitConverter.ToInt64);
        }
    }
}

I think the problem is created while creating object of type Huffman in public class MyClass. Could some one please help me how to get a rid of this problem by giving a solution (any piece of code would be highly appreciated)? Thanks. Important: I know why i get this Unhandled exception error. Its just due to this Object declaration :

A <long> ObjSym = new A <long> (args, BitConverter.ToInt64);

But if i do so there is no error at all.

A <short> ObjSym = new A <short> (args, BitConverter.ToInt16);

But it gives wrong output (because it read 2 bytes together but I want read only 1 byte at a time). The error disappears, The error was because this file must be the multiple of 16 in case of BitConverter.ToInt16 and multiple of 64 in case of BitConverter.ToInt64.

Where as to get the correct output from this binary file I must have something like : A ObjSym = new A (args, BitConverter.ToInt8);

It is because the size of byte is "8 bits" and I have to read each "8 bits" But I found no data type in C# which could hold 8 bits for example as I have kept "short" for BitConverter.Toint16 and "long" for Bitconverter.Toint64 and may others. Could some one please tell me it's "8 bit equivalent integer type ?" would be a big help. Thanks

Was it helpful?

Solution

The issue is in the line:

byte[] bytes = stream.ReadBytes(size);

When the method stream.ReadBytes reads < 8 bytes, then byte[] array has a length < 8 and in the method BitConverter.ToInt64(byte[] value, int startIndex) occurs the error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top