TextBinaryFileId.cs

Determine Byte Array Binary or Text

Updated: March-5, 2022

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
public class TextBinaryFileId
{
    private readonly BoyerMooreByte             _boyerMoore4Null = new(new byte[] { 0, 0, 0, 0 });
    public           Dictionary<string, string> BinaryFiles      = new();
    public           Dictionary<string, string> EncodingFiles    = new();
    public           Dictionary<string, double> TextFiles        = new();
    public bool IsBlockText(byte[] BinData, double ConfidenceThreshold = 25)
    {
        if (BinData.Length == 0)
            return false;
        if (_boyerMoore4Null.Search(BinData) != -1)
            return false;
        var enc     = GetEncoding(BinData);
        var CcCount = BinData.AsParallel().Count(b => !IsValidTextByte(b, !(enc == Encoding.Unicode || enc == Encoding.UTF8 || enc == Encoding.UTF7 || enc == Encoding.ASCII)));
        var asp     = (double)CcCount / BinData.Length * 100d;
        return !(asp > ConfidenceThreshold);
    }
    public byte[] ReadBytes(string path)
    {
        try
        {
            var ba  = File.ReadAllBytes(path);
            var enc = GetEncoding(ba);
            EncodingFiles.Add(path, enc.EncodingName);
            if (Equals(enc, Encoding.UTF7) || Equals(enc, Encoding.UTF8) || Equals(enc, Encoding.ASCII)) return ba;
            if (Equals(enc, Encoding.Unicode))
            {
                var len  = ba.Length - 2;
                var blen = len / 2;
                if (blen * 2 < len) blen++;
                var b = new byte[blen];
                for (int i = 2, j = 0; i < ba.Length && j < blen; i += 2, ++j)
                    b[j] = ba[i];
                return b;
            }
            if (Equals(enc, Encoding.UTF32))
            {
                var len1  = ba.Length - 4;
                var blen1 = len1 / 4;
                if (blen1 * 4 < len1)
                    blen1++;
                var b1 = new byte[blen1];
                for (int i = 4, j = 0; i < ba.Length && j < blen1; i += 4, ++j)
                    b1[j] = ba[i];
                return b1;
            }
            return ba;
        }
        catch (Exception ex)
        {
            ExceptionLog.ExLog(ex, "ReadBytes", "ReadBytes");
        }
        return null;
    }
    public bool IsTextQik(string path, bool TestEntireFile = false)
    {
        var    isText = true;
        double asp    = 0;
        using (var fileStream = File.OpenRead(path))
        {
            var WindowSize = 0l;
            if (TestEntireFile)
            {
                WindowSize = fileStream.Length;
            }
            else
            {
                WindowSize = 512;
                if (WindowSize > fileStream.Length)
                    WindowSize = fileStream.Length;
            }
            if (fileStream.Length == 0)
                return false;
            var BinData = new byte[WindowSize];
            fileStream.Read(BinData, 0, BinData.Length);
            if (fileStream.Length < 4)
            {
                foreach (var b in BinData)
                    if (!IsValidTextByte(b))
                        return false;
                return true;
            }
            if (_boyerMoore4Null.Search(BinData) != -1)
                isText = false;
            if (!ComfirmIsText(BinData))
                isText = false;
        }
        return isText;
    }
    public bool IsTextQik(byte[] buffer, bool TestEntireFile = false)
    {
        var    isText = true;
        double asp    = 0;
        if (buffer.Length == 0)
            return false;
        var WindowSize = 0;
        if (TestEntireFile)
        {
            WindowSize = buffer.Length;
        }
        else
        {
            WindowSize = 512;
            if (WindowSize > buffer.Length)
                WindowSize = buffer.Length;
        }
        var BinData = buffer.SubArray(0, WindowSize);
        if (BinData.Count(b => !IsValidTextByte(b)) > 0)
            return false;
        if (_boyerMoore4Null.Search(BinData) != -1)
            return false;
        return true;
    }
    public bool IsText(string path, bool TestEntireFile = false, double ConfidenceThreshold = 100, bool TestEncoding = true)
    {
        var    Reason = "None";
        var    isText = true;
        double asp    = 0;
        using (var fileStream = File.OpenRead(path))
        {
            var WindowSize = 0l;
            if (TestEntireFile)
            {
                WindowSize = fileStream.Length;
            }
            else
            {
                WindowSize = 512;
                if (WindowSize > fileStream.Length)
                    WindowSize = fileStream.Length;
            }
            if (fileStream.Length == 0)
            {
                BinaryFiles.Add(path, "Zero Length File.");
                return false;
            }
            var BinData       = new byte[WindowSize];
            var BinDataLength = fileStream.Read(BinData, 0, BinData.Length);
            fileStream.Seek(0, SeekOrigin.Begin);
            if (fileStream.Length < 4)
            {
                var r = BinData.All(b => IsValidTextByte(b));
                if (!r)
                    BinaryFiles.Add(path, "Length 4 file Contains invalid Characters.");
                return r;
            }
            if (_boyerMoore4Null.Search(BinData) != -1)
            {
                Reason = "4 Sequential Nulls Found within File.";
                isText = false;
            }
            if (isText)
            {
                var enc = GetEncoding(BinData);
                if (TestEncoding)
                {
                    var TextData = new char[WindowSize];
                    var eMatches = 0;
                    using (var streamReader = new StreamReader(fileStream))
                    {
                        streamReader.Read(TextData, 0, TextData.Length);
                    }
                    using (var memoryStream = new MemoryStream())
                    {
                        using (var streamWriter = new StreamWriter(memoryStream, enc))
                        {
                            streamWriter.Write(TextData);
                            streamWriter.Flush();
                            var memoryBuffer = memoryStream.GetBuffer();
                            for (var i = 0; i < BinDataLength; i++)
                                if (BinData[i] == memoryBuffer[i])
                                    eMatches++;
                            var er = (double)eMatches / BinDataLength * 100d;
                            if ((int)er < 99)
                            {
                                isText = false;
                                Reason = $"Encoding Mismatch: {er:0.0}";
                            }
                        }
                    }
                }
                if (isText)
                {
                    double CcCount = BinData.AsParallel().Count(b =>
                        !IsValidTextByte(b, !(enc == Encoding.Unicode || enc == Encoding.UTF8 || enc == Encoding.UTF7 || enc == Encoding.ASCII)));
                    asp = CcCount / BinData.Length * 100d;
                    if (asp > ConfidenceThreshold)
                    {
                        Reason = $"Confidence threshold {ConfidenceThreshold:0.0} Exceeded: {asp:0.0}";
                        isText = false;
                    }
                }
            }
        }
        if (isText)
            TextFiles.Add(path, asp.TruncateToDecimalPlace(1));
        else
            BinaryFiles.Add(path, Reason);
        return isText;
    }
    public static Encoding GetEncoding(byte[] Data)
    {
        if (Data == null)
            throw new Exception("Array cannot be null.");
        if (Data.Length < 2)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe)
            return Encoding.Unicode;
        if (Data[0] == 0xfe && Data[1] == 0xff)
            return Encoding.BigEndianUnicode;
        if (Data.Length < 3)
            return Encoding.Default;
        if (Data[0] == 0xef && Data[1] == 0xbb && Data[2] == 0xbf)
            return Encoding.UTF8;
        if (Data[0] == 0x2b && Data[1] == 0x2f && Data[2] == 0x76)
            return Encoding.UTF7;
        if (Data.Length < 4)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe && Data[2] == 0 && Data[3] == 0)
            return Encoding.UTF32;
        return Encoding.Default;
    }
    public static bool ComfirmIsText(byte[] Data)
    {
        if (Data == null)
            throw new Exception("Array cannot be null.");
        if (Data.Length < 2)
            return false;
        if (Data[0] == 0xff && Data[1] == 0xfe)
            return true;
        if (Data[0] == 0xfe && Data[1] == 0xff)
            return true;
        if (Data.Length < 3)
            return false;
        if (Data[0] == 0xef && Data[1] == 0xbb && Data[2] == 0xbf)
            return true;
        if (Data[0] == 0x2b && Data[1] == 0x2f && Data[2] == 0x76)
            return true;
        if (Data.Length < 4)
            return false;
        if (Data[0] == 0xff && Data[1] == 0xfe && Data[2] == 0 && Data[3] == 0)
            return true;
        var ld = Data.SubArray(0, Data.Length >= 6 ? 6 : Data.Length);
        foreach (var b in ld)
            if (!IsValidTextByte(b))
                return false;
        return true;
        ;
    }
    private static bool IsValidTextByte(byte _byte, bool IncludeNull = false)
    {
        if (IncludeNull)
            if (_byte == 0x00)
                return true;
        if (_byte == 0x0A || _byte == 0x0D || _byte == 0x09 || (_byte >= 0x20 && _byte <= 0x2F) || (_byte >= 0x30 && _byte <= 0x39) || (_byte >= 0x3A && _byte <= 0x40) ||
            (_byte >= 0x41 && _byte <= 0x5A) || (_byte >= 0x5B && _byte <= 0x60) || (_byte >= 0x61 && _byte <= 0x7A) || (_byte >= 0x7B && _byte <= 0x7E))
            return true;
        return false;
    }
}

Reader.cs

Simplified Binary Reader

Example Code:

using System;
using System.IO;
using System.Numerics;
using System.Text;
/// <inheritdoc />
/// <summary>
///     Alternate Binary Reader created to ease usability and complexity of coding.
/// </summary>
public class Reader : IDisposable
{
    /// <inheritdoc />
    /// <summary>
    ///     Initializes a new instance of the Reader class based on a specified path name, and defaulting to UTF-8 encoding.
    /// </summary>
    public Reader(string path) : this(path, new UTF8Encoding(false, true))
    {
    }
    /// <summary>
    ///     Initializes a new instance of the Reader class based on a specified path name, a specified encoding.
    /// </summary>
    public Reader(string path, Encoding encoding)
    {
        if (string.IsNullOrEmpty(path))
            throw new Exception($"Path {path} cannot be null or empty.");
        try
        {
            File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Normal);
            BaseStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            if (BaseStream?.CanRead == true)
                BaseReader = new BinaryReader(BaseStream, encoding);
            else throw new Exception($"The FileStream for path:{path} is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    public Reader(Stream strm) : this(strm, new UTF8Encoding(false, true))
    {
    }
    public Reader(Stream strm, Encoding encoding)
    {
        try
        {
            if (strm?.CanRead == true)
                BaseReader = new BinaryReader(strm, encoding);
            else throw new Exception("The Stream is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    /// <summary>
    ///     Expose the underlying BinaryReader
    /// </summary>
    public BinaryReader BaseReader { get; }
    /// <summary>
    ///     Expose the underlying FileStream
    /// </summary>
    public FileStream BaseStream { get; }
    /// <summary>
    ///     Each time a primitive is written there is one additional integer written to signify its type.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int PrimitiveOverHead => sizeof(int);
    /// <summary>
    ///     Each time a array is written there are two additional integers written one to signify its type and the other its
    ///     size.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int ArrayOverHead => sizeof(int) * 2;
    public void Dispose()
    {
        BaseStream?.Dispose();
    }
    /// <summary>
    ///     Sets the position to offset relative to origin within the stream.
    /// </summary>
    public long Seek(int offset, SeekOrigin origin)
    {
        return BaseStream.Seek(offset, origin);
    }
    /// <summary>
    ///     A wrapper for PeekChar of BinaryReader underling class.
    /// </summary>
    public int PeekChar()
    {
        return BaseReader.PeekChar();
    }
    public bool ReadBool()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary boolean value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Boolean)
            throw new Exception($"Boolean value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadBoolean();
    }
    public char ReadChar()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Char value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Character)
            throw new Exception($"Character value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadChar();
    }
    public byte ReadByte()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Byte value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Byte)
            throw new Exception($"Byte value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadByte();
    }
    public sbyte ReadSByte()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary short byte value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortByte)
            throw new Exception($"Short Byte value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadSByte();
    }
    public short ReadShort()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Short value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Short)
            throw new Exception($"Short value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt16();
    }
    public ushort ReadUShort()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Short value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedShort)
            throw new Exception($"Unsigned Short value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt16();
    }
    public int ReadInt()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Integer value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Integer)
            throw new Exception($"Integer value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt32();
    }
    public uint ReadUInt()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Integer value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedInteger)
            throw new Exception($"Unsigned Integer value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt32();
    }
    public long ReadLong()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Long value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Long)
            throw new Exception($"Long value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt64();
    }
    public ulong ReadULong()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Long value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedLong)
            throw new Exception($"Unsigned Long value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt64();
    }
    public string ReadString()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary String value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.String)
            throw new Exception($"String value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadString();
    }
    public float ReadFloat()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Float value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Float)
            throw new Exception($"Float value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadSingle();
    }
    public double ReadDouble()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Double value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Double)
            throw new Exception($"Double value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadDouble();
    }
    public decimal ReadDecimal()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Decimal value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Decimal)
            throw new Exception($"Decimal value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadDecimal();
    }
    public BigInteger ReadBigInteger()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigInteger value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigInteger)
            throw new Exception($"BigInteger value read requested '{Rwtypes.GetType(t)}' value found.");
        return new BigInteger(ReadBytes());
    }
    public BigRational ReadBigRational()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigRational value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigRational)
            throw new Exception($"BigRational value read requested '{Rwtypes.GetType(t)}' value found.");
        var Num = new BigInteger(ReadBytes());
        var Den = new BigInteger(ReadBytes());
        return new BigRational(Num, Den);
    }
    public bool[] ReadBools()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary boolean array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BooleanArray)
            throw new Exception($"Boolean Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new bool[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadBoolean();
        return arr;
    }
    public char[] ReadChars()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary char array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.CharacterArray)
            throw new Exception($"Character array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new char[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadChar();
        return arr;
    }
    public byte[] ReadBytes()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary byte array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ByteArray)
            throw new Exception($"Byte Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new byte[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadByte();
        return arr;
    }
    public sbyte[] ReadSBytes()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary sbyte array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortByteArray)
            throw new Exception($"Short Byte Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new sbyte[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadSByte();
        return arr;
    }
    public short[] ReadShorts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary short array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortArray)
            throw new Exception($"Short Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new short[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt16();
        return arr;
    }
    public ushort[] ReadUShorts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned short array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedShortArray)
            throw new Exception($"Unsigned Short Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new ushort[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt16();
        return arr;
    }
    public int[] ReadInts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary integer array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.IntegerArray)
            throw new Exception($"Integer Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new int[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt32();
        return arr;
    }
    public uint[] ReadUInts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned integer array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedInteger)
            throw new Exception($"Unsigned Integer Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new uint[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt32();
        return arr;
    }
    public long[] ReadLongs()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary long array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.LongArray)
            throw new Exception($"Long Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new long[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt64();
        return arr;
    }
    public ulong[] ReadULongs()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned long array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedLongArray)
            throw new Exception($"Unsigned Long Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new ulong[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt64();
        return arr;
    }
    public string[] ReadStrings()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary string array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.StringArray)
            throw new Exception($"String Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new string[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadString();
        return arr;
    }
    public float[] ReadFloats()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary float array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.FloatArray)
            throw new Exception($"Float Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new float[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadSingle();
        return arr;
    }
    public double[] ReadDoubles()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary double array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.DoubleArray)
            throw new Exception($"Double Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new double[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadDouble();
        return arr;
    }
    public decimal[] ReadDecimals()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary decimal array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.DecimalArray)
            throw new Exception($"Decimal Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new decimal[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadDecimal();
        return arr;
    }
    public BigInteger[] ReadBigIntegers()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigInteger array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigIntegerArray)
            throw new Exception($"BigInteger Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new BigInteger[len];
        for (var i = 0; i < len; ++i)
            arr[i] = ReadBigInteger();
        return arr;
    }
    public BigRational[] ReadBigRationals()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigRational array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigRationalArray)
            throw new Exception($"BigRational Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new BigRational[len];
        for (var i = 0; i < len; ++i)
            arr[i] = ReadBigRational();
        return arr;
    }
}