乱码问题 用IO流读取文本文件的时候,读出来的中文是乱码啊!怎么解决啊! 急急急急急急急急急急 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 输出流一定要设置 用UTF8格式显示咯 StreamReader sr = new StreamReader(Directory.GetCurrentDirectory() + "\\1.txt", Encoding.Default) 自己看下子http://wenku.baidu.com/view/1ca59d868762caaedd33d428.html 当我们用system.io.streamreader读取包含汉字的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 system.text; using system.io; namespace farproc.text { /// <summary> /// 用于取得一个文本文件的编码方式(encoding)。 /// </summary> public class txtfileencoding { public txtfileencoding() { // // todo: 在此处添加构造函数逻辑 // } /// <summary> /// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,encoding.default将被返回。 /// </summary> /// <param name="filename">文件名。</param> /// <returns></returns> public static encoding getencoding(string filename) { return getencoding(filename, encoding.default); } /// <summary> /// 取得一个文本文件流的编码方式。 /// </summary> /// <param name="stream">文本文件流。</param> /// <returns></returns> public static encoding getencoding(filestream stream) { return getencoding(stream, encoding.default); } /// <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, filemode.open); encoding targetencoding = getencoding(fs, defaultencoding); fs.close(); 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 && stream.length >= 2) { //保存文件流的前4个字节 byte byte1 = 0; byte byte2 = 0; byte byte3 = 0; byte byte4 = 0; //保存当前seek位置 long origpos = stream.seek(0, seekorigin.begin); stream.seek(0, seekorigin.begin); int nbyte = 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); } return targetencoding; } } } 由于在gb2312和utf7编码都没有bom,所以需要指定一个默认的encoding,在未找到合法的bom时,将返回这个 encoding。有谁知道怎么区分gb2312和utf7编码txt文件的方法,也请告诉我。 由于只是static方法,所以不用new,直接通过类名调用方法,使用起来也非常简单。 using system; using farproc.text; using system.text; using system.io; namespace consoleapplication1 { /// <summary> /// class1 的摘要说明。 /// </summary> class class1 { /// <summary> /// 应用程式的主入口点。 /// </summary> [stathread] static void main(string[] args) { // // todo: 在此处添加代码以启动应用程式 // string filename = @"e:\a.txt"; //生成一个big endian unicode编码格式的文本文件 streamwriter sw = new streamwriter(filename, false, encoding.bigendianunicode);//你能试试其他编码,比如encoding.getencoding("gb2312")或utf8 sw.write("这是个string"); sw.close(); //读取 encoding fileencoding = txtfileencoding.getencoding(filename, encoding.getencoding("gb2312"));//取得这txt文件的编码 console.writeline("这个文本文件的编码为:" + fileencoding.encodingname); streamreader sr = new streamreader(filename, fileencoding);//用该编码创建streamreader //用下面的方法虽然能让系统自动判断文本文件的编码格式,不过我们无法取得该文本文件的编码 //sr.currentencoding永远为 unicode(utf-8) //streamreader sr = new streamreader(filename, true); //console.writeline("这个文本文件的编码为:" + sr.currentencoding.encodingname); console.writeline("这个文本文件的内容为:" + sr.readtoend()); sr.close(); console.readline(); } } } 100分请教 金额录入控件 C# IAsyncResult 接口有哪些子类? winform调用dll问题 读取数据 winform中的方法哪些是静态、哪些是非静态 关于this 没钱紧急求助,数据查询+DataGrid绑定的困惑? 急急急! C#使用itextsharp.dll操作PDF 字符串的正则表达式校验问题 如何在listview和treeview之间实现item的拖放操作? C# 打印两个纠结的问题 怎么做提示框
StreamReader sr = new StreamReader(Directory.GetCurrentDirectory() + "\\1.txt", Encoding.Default)
http://wenku.baidu.com/view/1ca59d868762caaedd33d428.html
当我们用system.io.streamreader读取包含汉字的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 system.text; using system.io; namespace farproc.text { /// <summary> /// 用于取得一个文本文件的编码方式(encoding)。 /// </summary> public class txtfileencoding { public txtfileencoding() { // // todo: 在此处添加构造函数逻辑 // } /// <summary> /// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,encoding.default将被返回。 /// </summary> /// <param name="filename">文件名。</param> /// <returns></returns> public static encoding getencoding(string filename) { return getencoding(filename, encoding.default); } /// <summary> /// 取得一个文本文件流的编码方式。 /// </summary> /// <param name="stream">文本文件流。</param> /// <returns></returns> public static encoding getencoding(filestream stream) { return getencoding(stream, encoding.default); } /// <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, filemode.open); encoding targetencoding = getencoding(fs, defaultencoding); fs.close(); 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 && stream.length >= 2) { //保存文件流的前4个字节 byte byte1 = 0; byte byte2 = 0; byte byte3 = 0; byte byte4 = 0; //保存当前seek位置 long origpos = stream.seek(0, seekorigin.begin); stream.seek(0, seekorigin.begin); int nbyte = 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); } return targetencoding; } } } 由于在gb2312和utf7编码都没有bom,所以需要指定一个默认的encoding,在未找到合法的bom时,将返回这个 encoding。有谁知道怎么区分gb2312和utf7编码txt文件的方法,也请告诉我。 由于只是static方法,所以不用new,直接通过类名调用方法,使用起来也非常简单。 using system; using farproc.text; using system.text; using system.io; namespace consoleapplication1 { /// <summary> /// class1 的摘要说明。 /// </summary> class class1 { /// <summary> /// 应用程式的主入口点。 /// </summary> [stathread] static void main(string[] args) { // // todo: 在此处添加代码以启动应用程式 // string filename = @"e:\a.txt"; //生成一个big endian unicode编码格式的文本文件 streamwriter sw = new streamwriter(filename, false, encoding.bigendianunicode);//你能试试其他编码,比如encoding.getencoding("gb2312")或utf8 sw.write("这是个string"); sw.close(); //读取 encoding fileencoding = txtfileencoding.getencoding(filename, encoding.getencoding("gb2312"));//取得这txt文件的编码 console.writeline("这个文本文件的编码为:" + fileencoding.encodingname); streamreader sr = new streamreader(filename, fileencoding);//用该编码创建streamreader //用下面的方法虽然能让系统自动判断文本文件的编码格式,不过我们无法取得该文本文件的编码 //sr.currentencoding永远为 unicode(utf-8) //streamreader sr = new streamreader(filename, true); //console.writeline("这个文本文件的编码为:" + sr.currentencoding.encodingname); console.writeline("这个文本文件的内容为:" + sr.readtoend()); sr.close(); console.readline(); } } }