C#如何自动识别文件的编码
前言
C#中识别文件的编码是一个头疼的问题,最近在做导入微信商户后台退款数据时,无论怎么设置编码导出来都是乱码,后来在网上找了这个识别文件编码的代码,感觉不错。最后识别出来是gb2312,看来我还是太渣了,只能吃土了,竟然忘记了这个编码。
下面话不多说,上代码。
///<summary> ///用于取得一个文本文件的编码方式(Encoding)。 ///</summary> publicclassTxtFileEncoder { publicTxtFileEncoder() { // //TODO:在此处添加构造函数逻辑 // } ///<summary> ///取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。 ///</summary> ///<paramname="fileName">文件名。</param> ///<returns></returns> publicstaticEncodingGetEncoding(stringfileName) { returnGetEncoding(fileName,Encoding.Default); } ///<summary> ///取得一个文本文件流的编码方式。 ///</summary> ///<paramname="stream">文本文件流。</param> ///<returns></returns> publicstaticEncodingGetEncoding(FileStreamstream) { returnGetEncoding(stream,Encoding.Default); } ///<summary> ///取得一个文本文件的编码方式。 ///</summary> ///<paramname="fileName">文件名。</param> ///<paramname="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param> ///<returns></returns> publicstaticEncodingGetEncoding(stringfileName,EncodingdefaultEncoding) { FileStreamfs=newFileStream(fileName,FileMode.Open); EncodingtargetEncoding=GetEncoding(fs,defaultEncoding); fs.Close(); returntargetEncoding; } ///<summary> ///取得一个文本文件流的编码方式。 ///</summary> ///<paramname="stream">文本文件流。</param> ///<paramname="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param> ///<returns></returns> publicstaticEncodingGetEncoding(FileStreamstream,EncodingdefaultEncoding) { EncodingtargetEncoding=defaultEncoding; if(stream!=null&&stream.Length>=2) { //保存文件流的前4个字节 bytebyte1=0; bytebyte2=0; bytebyte3=0; bytebyte4=0; //保存当前Seek位置 longorigPos=stream.Seek(0,SeekOrigin.Begin); stream.Seek(0,SeekOrigin.Begin); intnByte=stream.ReadByte(); byte1=Convert.ToByte(nByte); byte2=Convert.ToByte(stream.ReadByte()); if(stream.Length>=3) { byte3=Convert.ToByte(stream.ReadByte()); } if(stream.Length>=4) { byte4=Convert.ToByte(stream.ReadByte()); } //根据文件流的前4个字节判断Encoding //Unicode{0xFF,0xFE}; //BE-Unicode{0xFE,0xFF}; //UTF8={0xEF,0xBB,0xBF}; if(byte1==0xFE&&byte2==0xFF)//UnicodeBe { targetEncoding=Encoding.BigEndianUnicode; } if(byte1==0xFF&&byte2==0xFE&&byte3!=0xFF)//Unicode { targetEncoding=Encoding.Unicode; } if(byte1==0xEF&&byte2==0xBB&&byte3==0xBF)//UTF8 { targetEncoding=Encoding.UTF8; } //恢复Seek位置 stream.Seek(origPos,SeekOrigin.Begin); } returntargetEncoding; } //新增加一个方法,解决了不带BOM的UTF8编码问题 ///<summary> ///通过给定的文件流,判断文件的编码类型 ///</summary> ///<paramname="fs">文件流</param> ///<returns>文件的编码类型</returns> publicstaticSystem.Text.EncodingGetEncoding(Streamfs) { byte[]Unicode=newbyte[]{0xFF,0xFE,0x41}; byte[]UnicodeBIG=newbyte[]{0xFE,0xFF,0x00}; byte[]UTF8=newbyte[]{0xEF,0xBB,0xBF};//带BOM EncodingreVal=Encoding.Default; BinaryReaderr=newBinaryReader(fs,System.Text.Encoding.Default); byte[]ss=r.ReadBytes(4); if(ss[0]==0xFE&&ss[1]==0xFF&&ss[2]==0x00) { reVal=Encoding.BigEndianUnicode; } elseif(ss[0]==0xFF&&ss[1]==0xFE&&ss[2]==0x41) { reVal=Encoding.Unicode; } else { if(ss[0]==0xEF&&ss[1]==0xBB&&ss[2]==0xBF) { reVal=Encoding.UTF8; } else { inti; int.TryParse(fs.Length.ToString(),outi); ss=r.ReadBytes(i); if(IsUTF8Bytes(ss)) reVal=Encoding.UTF8; } } r.Close(); returnreVal; } ///<summary> ///判断是否是不带BOM的UTF8格式 ///</summary> ///<paramname="data"></param> ///<returns></returns> privatestaticboolIsUTF8Bytes(byte[]data) { intcharByteCounter=1;//计算当前正分析的字符应还有的字节数 bytecurByte;//当前分析的字节. for(inti=0;i<data.Length;i++) { curByte=data[i]; if(charByteCounter==1) { if(curByte>=0x80) { //判断当前 while(((curByte<<=1)&0x80)!=0) { charByteCounter++; } //标记位首位若为非0则至少以2个1开始如:110XXXXX...........1111110X if(charByteCounter==1||charByteCounter>6) { returnfalse; } } } else { //若是UTF-8此时第一位必须为1 if((curByte&0xC0)!=0x80) { returnfalse; } charByteCounter--; } } if(charByteCounter>1) { thrownewException("非预期的byte格式!"); } returntrue; } }
总结
以上就是C#自动识别文件编码的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。