2008年8月22日 星期五

c#在byte[]陣列裡找值 在檔案串流裡找值

自己寫了幾個.net沒有提供 可是我覺得很常用的C#函式
跟大家分享一下

1.        byte[]陣列裡搜尋找值,要找的值可以是一個byte陣列,函式會回傳第一個出現的位置,string類的indexof很像
 
        private int byteArrayIndexOf(byte[] input, byte[] byte_match, int offset)
        {
            int maxindex = input.Length - byte_match.Length + 1;
            for (int i = offset; i < maxindex; i++)
            {
                bool match_flag = true;
                for (int j = 0; j < byte_match.Length; j++)
                {
                    if (input[i + j] != byte_match[j])
                    {
                        match_flag = false;
                        break;
                    }
                }
                //判定結果  如果是就回傳當前index
                if (match_flag == true)
                {
                    return i;
                }
            }
            return -1;//找不到就回傳-1
        }
 
2.        在檔案串流裡搜尋找值,傳進的是binaryreader,跟第一個一樣,傳回第一次出現的位置,由於效率的關係,如果一個byte一個byte從檔案串流比對,速度會非常慢,因此好的做法應該是一次讀進一個blockbyte[]陣列,然後再利用上面的在byte[]陣列搜尋算出特定直在檔案裡出現的位置,因為對byte[]陣列的操作是屬於記憶體層次,因此速度會快非常多倍
 
        private int binaryStreamIndexOf(BinaryReader input, byte[] byte_match, int offset)
        {
            int TESTBUFFER_SIZE = 64000; //一次讀64k進來運算提高效率
            for (int i = 0; offset + i * TESTBUFFER_SIZE < input.BaseStream.Length; i++)
            {
                input.BaseStream.Position = offset + i * TESTBUFFER_SIZE;
                byte[] testBuffer = new byte[0];
                if (offset + (i + 1) * TESTBUFFER_SIZE < input.BaseStream.Length)
                {
                    //讀進TESTBUFFER_SIZE的長度
                    testBuffer = input.ReadBytes(TESTBUFFER_SIZE);
                }
                else
                {
                    //代表剩下不足TESTBUFFER_SIZE的長度  全部讀進來
                    testBuffer = input.ReadBytes((int)input.BaseStream.Length - (offset + i * TESTBUFFER_SIZE));
                }
                //testBuffer中尋找
                int index_found = byteArrayIndexOf(testBuffer, byte_match, 0);
                if (index_found > -1)
                {
                    return offset + i * TESTBUFFER_SIZE + index_found;
                }
            }
            return -1;//找不到就回傳-1
        }
 
3.        依照所指定的位置和長度,在一個大的byte[]陣列中分割出小的byte[]陣列,類似stringsubstring()
 
        private byte[] byteGetSubArray(byte[] input, int index_start, int length)
        {
            byte[] newArray;
            newArray = new byte[length];
            Array.Copy(input, index_start, newArray, 0, length);
            return newArray;
        }