就是用C#设计一个类似XP自带的记事本,能打开任何(至少是我电脑上的)文本文件,不会出中文乱码

lin6234123456 2006-11-02 10:50:47
见另一个贴!
...全文
2378 50 打赏 收藏 举报
写回复
50 条回复
切换为时间正序
请发表友善的回复…
发表回复
股神 2006-11-03
  • 打赏
  • 举报
回复
up
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
这个问题也讨论得差不多了,明天结贴.来者都有分.

936_简体中文(GB2312)
950_繁体中文(Big5)
1200_Unicode
1201_Unicode (Big-Endian)
10002_繁体中文(Mac)
10008_简体中文(Mac)
12000_Unicode (UTF-32)
12001_Unicode (UTF-32 Big-Endian)
20000_繁体中文(CNS)
20001_TCA 台湾
20002_繁体中文(Eten)
20003_IBM5550 台湾
20004_TeleText 台湾
20005_Wang 台湾
20936_简体中文(GB2312-80)
50227_简体中文(ISO-2022)
51936_简体中文(EUC)
52936_简体中文(HZ)
54936_简体中文(GB18030)
65000_Unicode (UTF-7)
65001_Unicode (UTF-8)
yunyu97 2006-11-03
  • 打赏
  • 举报
回复
xp的记事本其实很简单的。它能够判断的只有几种格式,也就是ANSI(本地编码),Unicode,Unicode big endian,以及UTF-8编码。
要判断编码是哪种格式,首先看前几个字节,utf-8前面是ef,bb,bf这三个,unicode是ff fe,unicode big endian是fe ff,big endian的情况在little endian的cup上要将读入的前后两个字节反过来。用ue查看utf8二进制文件的时候要在设置中将自动转换utf8文件这一项关闭,否则ue会将utf8转换为Unicode格式后再显示。除了上述情况以外,其余的默认都是ANSI本地编码。这个编码一般用当前windows默认的本地编码显示,windows默认的本地编码是指在区域选项-高级-非Unicode程序语言中指定的编码,或者用api读取当前的本地区域码。然后将读入的文本转换为Unicode编码再进行显示和处理。但是文本文件的本地编码有可能不符合当前windows的指定区域,这种情况就需要用户来进行编码选择了。比如你在简体中文windowsXP中创建一篇简体ANSI文档后再到区域选项中将非Unicode语言改为中文(台湾),那么重启系统后再用记事本打开这篇文档就会发现有乱码显示。对付这种情况一般是将文档中的本地编码在对应的字符集中寻找,如果找到一定字数,就可以认为是某种字符集了。需要说明的是这种辨认方法并不是很可靠,因为不同字符集有可能有交集。但对于只需要简体以及繁体识别的程序来说一般是足够了。简体GB18030编码以及繁体Big5编码是用的比较多的编码,这些编码都是Big endian,而且是单双字节混合编码,处理的时候先转换为Unicode比较好处理,其编码具体的资料可以到网上查找。
Qim 2006-11-03
  • 打赏
  • 举报
回复
研究一下windows 自带的写字板也不错。
Qim 2006-11-03
  • 打赏
  • 举报
回复
类似XP自带的记事本,能打开任何(至少是我电脑上的)文本文件,不会出中文乱码.

记事本能打开不出现乱码吗?

你要是说做个word ,不就更清楚了?
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
谢谢liangxf0022(小新),"Nodepad确实是一个复杂的判断过程。",不知道"内核 + 编码"中这个"内核"指什么,是指操作系统的内核吗?另外unicode = utf8 ?
我这个问题纯业余讨论,上面我说得"2、也就是说上面提的文本文件2.txt我用XP的记事本不会乱码,但用我编了一个小程序会乱码,这个文本文件2.txt只有UTF8不会出现乱码,但确不符合“UTF8 = {0xEF, 0xBB”, 0xBF};”所以是基本搞定。"
本文已基本上是送分贴了(因为自已已基本搞定),如果谁能帮我全部搞定(但我测试用的文本文件2.txt已破坏,不好检测!,看我前面发的).
一般情况,编码并不很复杂,但要像Nodepad一样,还时要花点心思(因为自已才基本搞定!).

大家继续发表的看法
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
谢谢liangxf0022(小新),"Nodepad确实是一个复杂的判断过程。",不知道"内核 + 编码"中这个"内核"指什么,是指操作系统的内核吗?另外unicode = utf8 ?
我这个问题纯业余讨论,上面我说得"2、也就是说上面提的文本文件2.txt我用XP的记事本不会乱码,但用我编了一个小程序会乱码,这个文本文件2.txt只有UTF8不会出现乱码,但确不符合“UTF8 = {0xEF, 0xBB”, 0xBF};”所以是基本搞定。"
本文已基本上是送分贴了(因为自已已基本搞定),如果谁能帮我全部搞定(但我测试用的文本文件2.txt已破坏,不好检测!,看我前面发的).
一般情况,编码并不很复杂,但要像Nodepad一样,还时要花点心思(因为自已才基本搞定!).

大家继续发表的看法
liangxf0022 2006-11-03
  • 打赏
  • 举报
回复
其实编码远远没有LZ想得那么复杂,跟操作系统的内码有关。另外,Nodepad确实是一个复杂的判断过程。至少ANSI和UTF8还是好区分的,判断文件里有没有字符的ASCII大于128的字符就可以了。但是C#已经内含了对多语言的支持,所以要得到字符的ASCII并不容易。

有几种情况罗列一下:
内核 + 编码
1、中文 + UTF8 = 支持中文和其他字符
2、中文 + ANSI = 支持中文
3、英文 + gb2312/gbk = 如果内核中有gb2312则支持,如果没有则乱码
3、英文 + UTF8 = 支持一切扩展字符,但需要内核有相应的编码
4、英文 + ANSI = 仅支持英文

还有就是GBK = gb2312 + Big5 + 生僻字
unicode = utf8
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
这个问题我自已基本上搞定了。{袁晓辉}
但是为什么说是基本搞定的,说来话长:
1、我电脑上有一个文本文件2.txt,我用了(unicode,gb2312,utf8,gbk等7个),结果只有UTF8不会出现乱码,但我确用上面[袁晓辉]的代码检测不是UTF8,也就是说我编了一个小程序,除了上面提的文本文件2.txt,其他的都通过了(我只测试了二十个左右文本文件)。
2、也就是说上面提的文本文件2.txt我用XP的记事本不会乱码,但用我编了一个小程序会乱码,这个文本文件2.txt只有UTF8不会出现乱码,但确不符合“UTF8 = {0xEF, 0xBB”, 0xBF};”所以是基本搞定。
3、这个文本文件2.txt已经破坏,无法复原。破坏过程是这样的,我在XP的记事本打开文本文件2.txt进行修改,在前面加上数字"123",然后保存,结果用我编的记事本能打开(不会乱码),我用另一个程序测用了(unicode,gb2312,utf8,gbk等7个),很多都不会出现乱码,然后我把数字"123"删除(在XP的记事本下),结果用了(unicode,gb2312,utf8,gbk等7个),还是不会出现乱码,这个文本文件2.txt已经不是当初的文本文件2.txt(虽然在在XP的记事本下内容是一样的!!!),呜呼!我的测试专用文本文件2.txt!!!!

大家发表的看法,为什么会这样?
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
楼上的,谢谢你的参与,但"能打开任何(至少是我电脑上的)文本文件,不会出中文乱码"这句,你自己测试过个吗(unicode,gb2312,utf8,gbk等7几种编码)?这些贴子你都看了?
wumylove1234 2006-11-03
  • 打赏
  • 举报
回复
好帖.Mark
Qim 2006-11-03
  • 打赏
  • 举报
回复
说简单点,就是用C#设计一个类似XP自带的记事本,能打开任何(至少是我电脑上的)文本文件,不会出中文乱码.只要这样一个功能(但不能临时去选取不同的编码),解决了分不成问题.从网上下载的几个记事本都没有解决这个问题.

楼主的意图不就在此吗?
Qim 2006-11-03
  • 打赏
  • 举报
回复
楼主,我的代码可以正常 动行。
只是代码看起来多。但是逻辑不复杂。
很浅显易懂.
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
zhuaiman((尘)╭∩╮(︶︿︶)╭∩╮) 以及Qim(莫名) 两位辛苦了,只是两位发代码时要看清要求,我不要这么一大堆的代码,关键是要击中要害.一般的代码网上有的是,本人言语直率见谅!!
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
这个问题我自已基本上搞定了。
但是为什么说是基本搞定的,说来话长:
1、我电脑上有一个文本文件2.txt,我用了(unicode,gb2312,utf8,gbk等7个),结果只有UTF8不会出现乱码,但我确用上面[袁晓辉]的代码检测不是UTF8,也就是说我编了一个小程序,除了上面提的文本文件2.txt,其他的都通过了(我只测试了二十个左右文本文件)。
2、也就是说上面提的文本文件2.txt我用XP的记事本不会乱码,但用我编了一个小程序会乱码,这个文本文件2.txt只有UTF8不会出现乱码,但确不符合“UTF8 = {0xEF, 0xBB”, 0xBF};”所以是基本搞定。
3、这个文本文件2.txt已经破坏,无法复原。破坏过程是这样的,我在XP的记事本打开文本文件2.txt进行修改,在前面加上数字"123",然后保存,结果用我编的记事本能打开(不会乱码),我用另一个程序测用了(unicode,gb2312,utf8,gbk等7个),很多都不会出现乱码,然后我把数字"123"删除(在XP的记事本下),结果用了(unicode,gb2312,utf8,gbk等7个),还是不会出现乱码,这个文本文件2.txt已经不是当初的文本文件2.txt(虽然在在XP的记事本下内容是一样的!!!),呜呼!我的测试专用文本文件2.txt!!!!

大家发表的看法,为什么会这样?
lin6234123456 2006-11-03
  • 打赏
  • 举报
回复
谢谢www_123du_com(鼠·神·泪),这个问题我自已基本上搞定了.就是我另一个贴子提到的(如下)
// 作者:袁晓辉
// 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();
}
}
}

但是为什么说是基本搞定的,说来话长:
1、我电脑上有一个文本文件2.txt,我用了(unicode,gb2312,utf8,gbk等7个),结果只有UTF8不会出现乱码,但我确用上面[袁晓辉]的代码检测不是UTF8,也就是说我编了一个小程序,除了上面提的文本文件2.txt,其他的都通过了(我只测试了二十个左右文本文件)。
2、也就是说上面提的文本文件2.txt我用XP的记事本不会乱码,但用我编了一个小程序会乱码,这个文本文件2.txt只有UTF8不会出现乱码,但确不符合“UTF8 = {0xEF, 0xBB”, 0xBF};”所以是基本搞定。
3、这个文本文件2.txt已经破坏,无法复原。破坏过程是这样的,我在XP的记事本打开文本文件2.txt进行修改,在前面加上数字"123",然后保存,结果用我编的记事本能打开(不会乱码),我用另一个程序测用了(unicode,gb2312,utf8,gbk等7个),很多都不会出现乱码,然后我把数字"123"删除(在XP的记事本下),结果用了(unicode,gb2312,utf8,gbk等7个),还是不会出现乱码,这个文本文件2.txt已经不是当初的文本文件2.txt(虽然在在XP的记事本下内容是一样的!!!),呜呼!我的测试专用文本文件2.txt!!!!
aling9801 2006-11-03
  • 打赏
  • 举报
回复
.NET Framework 类库
Encoding 类
表示字符编码。

命名空间:System.Text
程序集:mscorlib(在 mscorlib.dll 中)

语法



C#[SerializableAttribute]
[ComVisibleAttribute(true)]
public abstract class Encoding : ICloneable


备注

编码是一个将一组 Unicode 字符转换为一个字节序列的过程。解码是一个反向操作过程,即将一个编码字节序列转换为一组 Unicode 字符。

Unicode 标准为所有支持脚本中的每个字符分配一个码位(一个数字)。Unicode 转换格式 (UTF) 是一种码位编码方式。Unicode 标准 3.2 版使用下列 UTF:

UTF-8,它将每个码位表示为一个由 1 至 4 个字节组成的序列。

UTF-16,它将每个码位表示为一个由 1 至 2 个 16 位整数组成的序列。

UTF-32,它将每个码位表示为一个 32 位整数。

.NET Framework 提供以下 Encoding 类的实现以支持当前 Unicode 编码和其他编码:

ASCIIEncoding 将 Unicode 字符编码为单个 7 位 ASCII 字符。此编码仅支持 U+0000 和 U+007F 之间的字符值。代码页 20127。还可通过 ASCII 属性获得。

UTF7Encoding 使用 UTF-7 编码对 Unicode 字符进行编码。此编码支持所有 Unicode 字符值。代码页 65000。还可通过 UTF7 属性获得。

UTF8Encoding 使用 UTF-8 编码对 Unicode 字符进行编码。此编码支持所有 Unicode 字符值。代码页 65001。还可通过 UTF8 属性获得。

UnicodeEncoding 使用 UTF-16 编码对 Unicode 字符进行编码。支持 Little-Endian(代码页 1200)和 Big-Endian(代码页 1201)字节顺序。还可通过 Unicode 属性和 BigEndianUnicode 属性获得。

UTF32Encoding 使用 UTF-32 编码对 Unicode 字符进行编码。支持 Little-Endian(代码页 65005)和 Big-Endian(代码页 65006)字节顺序。还可通过 UTF32 属性获得。

使用 GetEncoding 方法以获取其他编码。使用 GetEncodings 方法来获取所有编码的列表。

下表列出编码以及与编码关联的代码页。最后一列中的星号指示 .NET Framework 本身即支持该代码页,而不需考虑基础平台。



GetByteCount 方法确定将有多少字节对一组 Unicode 字符进行编码,而 GetBytes 方法将执行实际的编码操作。

同样,GetCharCount 方法确定将有多少字符对字节序列进行解码,而 GetChars 方法执行实际的解码。

如果要转换的数据仅存在于连续块(如从流中读取的数据)中,或者数据量很大,需要划分为较小的块,则可使用由某个派生类的 GetDecoder 方法提供的 Decoder 或由派生类的 GetEncoder 方法提供的 Encoder。

UTF-16 和 UTF-32 编码器可以使用 Big-Endian 字节顺序(从最高有效字节开始),也可以使用 Little-Endian 字节顺序(从最低有效字节开始)。例如,大写拉丁字母 A (U+0041) 的序列化结果(十六进制)如下所示:

UTF-16 Big-Endian 字节顺序:00 41

UTF-16 Little-Endian 字节顺序:41 00

UTF-32 Big-Endian 字节顺序:00 00 00 41

UTF-32 Little-Endian 字节顺序:41 00 00 00

或者,Encoding 提供一个前导码(即一个字节数组),可以将它作为编码过程中所产生的字节序列的前缀。如果前导码中包含字节顺序标记(在 Unicode 中,码位为 U+FEFF),则它会帮助解码器确定字节顺序和转换格式或 UTF。Unicode 字节顺序标记的序列化结果(十六进制)如下所示:

UTF-8:EF BB BF

UTF-16 Big-Endian 字节顺序:FE FF

UTF-16 Little-Endian 字节顺序:FF FE

UTF-32 Big-Endian 字节顺序:00 00 FE FF

UTF-32 Little-Endian 字节顺序:FF FE 00 00

通常,使用本机字节顺序存储 Unicode 字符的效率更高。例如,在 Little-Endian 平台(如 Intel 计算机)上最好使用 Little-Endian 字节顺序。

GetPreamble 方法返回一个可以包括字节顺序标记的字节数组。如果将此字节数组作为编码流的前缀,将有助于解码器识别所用的编码格式。

有关字节顺序和字节顺序标记的更多信息,请参见 www.unicode.org 上的“The Unicode Standard”(Unicode 标准)部分。

aling9801 2006-11-03
  • 打赏
  • 举报
回复
解决读写包含汉字的txt文件时乱码的问题
[日期:2005-08-09] 来源:CSDN 作者:袁晓辉 [字体:大 中 小]

当我们用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();
}
}
}

.NET下的string永远是Unicode的,所以只能判断txt文件的Encoding。对于byte[],只有自己知道它的

Encoding才能转换为string 转换为其他编码的byte[],一个例外是把整个txt文件通过stream读入byte[]后也可以根据它的前几个字节判断

wuhuiITren 2006-11-03
  • 打赏
  • 举报
回复
wo lai la
zhuaiman 2006-11-02
  • 打赏
  • 举报
回复
控件板:一个菜单条 menuStrip1(Forms.MenuStrip) ,openFile开文件对话框(Forms.OpenFileDialog),saveFile保存文件对话框(Forms.SaveFileDialog)
加载更多回复(30)
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2006-11-02 10:50
社区公告

让您成为最强悍的C#开发者