C# 判斷文件流類型


public static class VerifyFileExtensionName
    {
        private static IDictionary<string, string> dics = new Dictionary<string, string>();

        static VerifyFileExtensionName()
        {
            dics.Add("FFD8FFE0", ".jpg");
            dics.Add("89504E47", ".png");
            dics.Add("47494638", ".gif");
            dics.Add("49492A00", ".tif");
            dics.Add("424D", ".bmp");

            //PS和CAD
            dics.Add("38425053", ".psd");
            dics.Add("41433130", ".dwg"); // CAD
            dics.Add("252150532D41646F6265", ".ps");

            //辦公文檔類
            dics.Add("D0CF11E0", ".doc"); //ppt、doc、xls
            dics.Add("504B0304", ".docx");//pptx、docx、xlsx    

            /**注意由於文本文檔錄入內容過多,則讀取文件頭時較為多變-START**/
            dics.Add("0D0A0D0A", ".txt");//txt
            dics.Add("0D0A2D2D", ".txt");//txt
            dics.Add("0D0AB4B4", ".txt");//txt        
            dics.Add("B4B4BDA8", ".txt");//文件頭部為漢字
            dics.Add("73646673", ".txt");//txt,文件頭部為英文字母
            dics.Add("32323232", ".txt");//txt,文件頭部內容為數字
            dics.Add("0D0A09B4", ".txt");//txt,文件頭部內容為數字
            dics.Add("3132330D", ".txt");//txt,文件頭部內容為數字      
            /**注意由於文本文檔錄入內容過多,則讀取文件頭時較為多變-END**/


            dics.Add("7B5C727466", ".rtf"); // 日記本

            dics.Add("255044462D312E", ".pdf");

            //視頻或音頻類
            dics.Add("3026B275", ".wma");
            dics.Add("57415645", ".wav");
            dics.Add("41564920", ".avi");
            dics.Add("4D546864", ".mid");
            dics.Add("2E524D46", ".rm");
            dics.Add("000001BA", ".mpg");
            dics.Add("000001B3", ".mpg");
            dics.Add("6D6F6F76", ".mov");
            dics.Add("3026B2758E66CF11", ".asf");

            //壓縮包
            dics.Add("52617221", ".rar");
            dics.Add("1F8B08", ".gz");

            //程序文件
            dics.Add("3C3F786D6C", ".xml");
            dics.Add("68746D6C3E", ".html");
            dics.Add("7061636B", ".java");
            dics.Add("3C254020", ".jsp");
            dics.Add("4D5A9000", ".exe");


            dics.Add("44656C69766572792D646174653A", ".eml"); // 郵件
            dics.Add("5374616E64617264204A", ".mdb");//Access數據庫文件

            dics.Add("46726F6D", ".mht");
            dics.Add("4D494D45", ".mhtml");
        }

        public static string GetFileType(Stream stream)
        {
            byte[] b = new byte[4];
            if (stream != null)
            {
                try
                {
                    stream.Read(b, 0, b.Length);

                    string fileType = System.Text.Encoding.UTF8.GetString(b);

                    DGHR.Util.Logger.Debug("文件類型:" + fileType);
                }
                catch (IOException e)
                {
                    DGHR.Util.Logger.Error(e);
                    return string.Empty;
                }
            }

            string fileKey = GetFileHeader(b);

            if (dics.ContainsKey(fileKey))
                return dics[fileKey];
            else
            {
                DGHR.Util.Logger.Info("未找到當前流的擴展名");
                return string.Empty;
            }
        }


        /**
         * 根據文件轉換成的字節數組獲取文件頭信息
         * 
         * @param filePath
         *            文件路徑
         * @return 文件頭信息
         */
        private static string GetFileHeader(byte[] b)
        {
            string value = BytesToHexString(b);
            return value;
        }

        /**
         * 將要讀取文件頭信息的文件的byte數組轉換成string類型表示
         * 下面這段代碼就是用來對文件類型作驗證的方法, 
         * 將字節數組的前四位轉換成16進制字符串,並且轉換的時候,要先和0xFF做一次與運算。
         * 這是因為,整個文件流的字節數組中,有很多是負數,進行了與運算后,可以將前面的符號位都去掉,
         * 這樣轉換成的16進制字符串最多保留兩位,如果是正數又小於10,那么轉換后只有一位,
         * 需要在前面補0,這樣做的目的是方便比較,取完前四位這個循環就可以終止了
         * @param src要讀取文件頭信息的文件的byte數組
         * @return 文件頭信息
         */
        private static string BytesToHexString(byte[] src)
        {
            StringBuilder builder = new StringBuilder();
            if (src == null || src.Length <= 0)
            {
                return null;
            }
            string hv;
            for (int i = 0; i < src.Length; i++)
            {
                // 以十六進制(基數 16)無符號整數形式返回一個整數參數的字符串表示形式,並轉換為大寫
                hv = Convert.ToString(src[i] & 0xFF, 16).ToUpper();
                if (hv.Length < 2)
                {
                    builder.Append(0);
                }
                builder.Append(hv);
            }

            DGHR.Util.Logger.Info("轉換到為:" + builder.ToString());

            return builder.ToString();
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM