如何确定文件编码格式的方法

如何确定文件编码格式的方法,第1张

如何确定文件编码格式的方法??
当我们用SystemIOStreamReader读取包含汉字的txt文件时,经常会读出乱码(StreamWriater写文本文件也有类似的问题),原因很简单,就是文件的编码(encoding)和StreamReader/Writer的encoding不对应。
为了解决这个问题,我写了一个类,来取得一个文本文件的encoding,这样我们就可以创建对应的StreamReader和StreamWriter来读写,保证不会出现乱码现象。其实原理很简单,文本编辑器(比如XP自带的记事本)在生成文本文件时,如果编码格式和系统默认的编码(中文系统下默认为GB2312)不一致时,会在txt文件开头部分添加特定的“编码字节序标识(Encoding Bit Order Madk,简写为BOM)”,类似PE格式的"MZ"文件头。这样它在读取时就可以根据这个BOM来确定该文本文件生成时所使用的Encoding。这个BOM我们用记事本等程序打开默认是看不到的,但是用stream按字节读取时是可以读到的。我的这个TxtFileEncoding类就是根据这个BOM“文件头”来确定txt文件生成时用到的编码的。
// 作者:袁晓辉
// 2005-8-8
// // // // // //
using System;
using SystemText;
using SystemIO;
namespace FarprocText
{
/// <summary>
/// 用于取得一个文本文件的编码方式(Encoding)。
/// </summary>
public class TxtFileEncoding
{
public TxtFileEncoding()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,EncodingDefault将被返回。
/// </summary>
/// <param name="fileName">文件名。</param>
/// <returns></returns>
public static Encoding GetEncoding(string fileName)
{
return GetEncoding(fileName, EncodingDefault);
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <returns></returns>
public static Encoding GetEncoding(FileStream stream)
{
return GetEncoding(stream, EncodingDefault);
}
// <summary>
/// 取得一个文本文件的编码方式。
/// </summary>
/// <param name="fileName">文件名。</param>
/// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public static Encoding GetEncoding(string fileName, Encoding defaultEncoding)
{
FileStream fs = new FileStream(fileName, FileModeOpen);
Encoding targetEncoding = GetEncoding(fs, defaultEncoding);
fsClose();
return targetEncoding;
}
/// <summary>
/// 取得一个文本文件流的编码方式。
/// </summary>
/// <param name="stream">文本文件流。</param>
/// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>
/// <returns></returns>
public static Encoding GetEncoding(FileStream stream, Encoding defaultEncoding)
{
Encoding targetEncoding = defaultEncoding;
if(stream != null && streamLength >= 2)
{
//保存文件流的前4个字节
byte byte1 = 0;
byte byte2 = 0;
byte byte3 = 0;
byte byte4 = 0;
//保存当前Seek位置
long origPos = streamSeek(0, SeekOriginBegin);
streamSeek(0, SeekOriginBegin);
int nByte = streamReadByte();
byte1 = ConvertToByte(nByte);
byte2 = ConvertToByte(streamReadByte());
if(streamLength >= 3)
{
byte3 = ConvertToByte(streamReadByte());
}
if(streamLength >= 4)
{
byte4 = ConvertToByte(streamReadByte());
}
//根据文件流的前4个字节判断Encoding
//Unicode {0xFF, 0xFE};
//BE-Unicode {0xFE, 0xFF};
//UTF8 = {0xEF, 0xBB, 0xBF};
if(byte1 == 0xFE && byte2 == 0xFF)//UnicodeBe
{
targetEncoding = EncodingBigEndianUnicode;
}
if(byte1 == 0xFF && byte2 == 0xFE && byte3 != 0xFF)//Unicode
{
targetEncoding = EncodingUnicode;
}
if(byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF)//UTF8
{
targetEncoding = EncodingUTF8;
}
//恢复Seek位置 
streamSeek(origPos, SeekOriginBegin);
}
return targetEncoding;
}
}
}
由于在GB2312和UTF7编码都没有BOM,所以需要指定一个默认的Encoding,在找不到合法的BOM时,将返回这个Encoding。有谁知道如何区分GB2312和UTF7编码txt文件的方法,也请告诉我。
由于只是static方法,所以不用new,直接通过类名调用方法,使用起来也很简单。
using System;
using FarprocText;
using SystemText;
using SystemIO;
namespace ConsoleApplication1
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
string fileName = @"e:\atxt";
//生成一个big endian Unicode编码格式的文本文件
StreamWriter sw = new StreamWriter(fileName, false, EncodingBigEndianUnicode);//你可以试试其他编码,比如EncodingGetEncoding("GB2312")或UTF8
swWrite("这是一个String");
swClose();
//读取
Encoding fileEncoding = TxtFileEncodingGetEncoding(fileName, EncodingGetEncoding("GB2312"));//取得这txt文件的编码
ConsoleWriteLine("这个文本文件的编码为:" + fileEncodingEncodingName);
StreamReader sr = new StreamReader(fileName, fileEncoding);//用该编码创建StreamReader
//用下面的方法虽然可以让系统自动判断文本文件的编码格式,但是我们无法取得该文本文件的编码
//srCurrentEncoding永远为 Unicode(UTF-8)
//StreamReader sr = new StreamReader(fileName, true);
//ConsoleWriteLine("这个文本文件的编码为:" + srCurrentEncodingEncodingName);
ConsoleWriteLine("这个文本文件的内容为:" + srReadToEnd());
srClose();
ConsoleReadLine();
}
}
}
NET下的string永远是Unicode的,所以只能判断txt文件的Encoding。对于byte[],只有自己知道它的Encoding才能转换为string 转换为其他编码的byte[],一个例外是把整个txt文件通过stream读入byte[]后也可以根据它的前几个字节判断Encoding,对于片断,我们就无能为力了:)

可以通过以下方法来进行编码格式判断,输入一个字符串,之后返回字符串编码类型。
public static String getEncoding(String str) {
String encode = "GB2312";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是GB2312
String s = encode;
return s; //是的话,返回“GB2312“,以下代码同理
}
} catch (Exception exception) {
}
encode = "ISO-8859-1";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是ISO-8859-1
String s1 = encode;
return s1;
}
} catch (Exception exception1) {
}
encode = "UTF-8";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是UTF-8
String s2 = encode;
return s2;
}
} catch (Exception exception2) {
}
encode = "GBK";
try {
if (strequals(new String(strgetBytes(encode), encode))) { //判断是不是GBK
String s3 = encode;
return s3;
}
} catch (Exception exception3) {
}
return ""; //如果都不是,说明输入的内容不属于常见的编码格式。

1、查看数据库编码格式

mysql> show variables like 'character_set_database'

2、查看数据表的编码格式

mysql> show create table <表名>;

3、创建数据库时指定数据库的字符集

mysql>create database <数据库名> character set utf8;

4、创建数据表时指定数据表的编码格式

create table tb_books (
name varchar(45) not null,
price double not null,
bookCount int not null,
author varchar(45) not null ) default charset = utf8;

5、修改数据库的编码格式

mysql>alter database <数据库名> character set utf8;

6、修改数据表格编码格式

mysql>alter table <表名> character set utf8;

7、修改字段编码格式

mysql>alter table <表名> change <字段名> <字段名> <类型> character set utf8;
mysql>alter table user change username username varchar(20) character set utf8 not null;

1、文件编码格式一般指文件内文本字符采用什么样的字符集,通常简体中文windows采用GB2312,极个别文本字符采用utf-8字符集,2、有时文件编码格式也通常指代文件的类型,windows对程序或数据文件的识别,一般通过文件扩展名来完成,也就是通过扩展名来识别一个文件是数据文件、可执行文件、文本文件、音乐文件~~不知道你问得是什么意思

文件的字符集在Windows下有两种,一种是ANSI,一种Unicode。
对于Unicode,Windows支持了它的三种编码方式,一种是小尾编码(Unicode),一种是大尾编码(BigEndianUnicode),一种是UTF-8编码。
我们可以从文件的头部来区分一个文件是属于哪种编码。当头部开始的两个字节为 FF FE时,是Unicode的小尾编码;当头部的两个字节为FE FF时,是Unicode的大尾编码;当头部两个字节为EF BB时,是Unicode的UTF-8编码;当它不为这些时,则是ANSI编码。
按照如上所说,我们可以通过读取文件头的两个字节来判断文件的编码格式,代码如下(C#代码):
程序中SystemTextEncodingDefault是指 *** 作系统的当前 ANSI 代码页的编码。
public SystemTextEncoding GetFileEncodeType(string filename){ SystemIOFileStream fs = new SystemIOFileStream(filename, SystemIOFileModeOpen, SystemIOFileAccessRead); SystemIOBinaryReader br = new SystemIOBinaryReader(fs); Byte[] buffer = brReadBytes(2); if(buffer[0]>=0xEF) { if(buffer[0]==0xEF && buffer[1]==0xBB) { return SystemTextEncodingUTF8; } else if(buffer[0]==0xFE && buffer[1]==0xFF) { return SystemTextEncodingBigEndianUnicode; } else if(buffer[0]==0xFF && buffer[1]==0xFE) { return SystemTextEncodingUnicode; } else { return SystemTextEncodingDefault; } } else { return SystemTextEncodingDefault; }}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/yw/13367580.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-22
下一篇 2023-07-22

发表评论

登录后才能评论

评论列表(0条)

保存