网站建设中服务器的搭建方式,怎么制作安卓app,dw网站建设的心得体会,软件商店下载官方参考#xff1a;
1. 《C#高级编程》第六版
2. 文件流和数据流-C#程序设计教程 2010-7-11补充#xff1a; 发现了一篇讲编码的深入而全面的好文章http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html
向文件写入非字符类型数据 当向文件中写入非字符类型的…参考
1. 《C#高级编程》第六版
2. 文件流和数据流-C#程序设计教程 2010-7-11补充 发现了一篇讲编码的深入而全面的好文章http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html
向文件写入非字符类型数据 当向文件中写入非字符类型的数据时StreamWriter和BinaryWriter存在巨大差异。 StreamWriter是把各种类型的数据都转化成字符然后把字符按照一定的格式编码出来的数据写入文件中。 BinaryWriter是直接把数据在内存中的真实状态写入到文件中。 例子 class Program
{static void Main(string[] args){ FileStream fs File.Open(E:\\MyFile.txt, FileMode.OpenOrCreate, FileAccess.Write);StreamWriter sw new StreamWriter(fs);BinaryWriter bw new BinaryWriter(fs);sw.Write(100);bw.Write(100); }
} 用UEdit查看MyFile.txt的16进制码. sw的输出为31 30 30,占三个字节。代表了1, 0, 0的ASCII码。它输出的全是文本数据。 bw的输出为64 00 00 00 ,占四个字节。这正是100在内存中的真实状态。int类型占四个字节。 用记事本打开sw的输出显示为100 bw的输出显示为 d 因为100对应了ASCII码的d。 BinaryWriter写进去的东西StreamReader是认不出来的只能用BinaryReader的对应方法来读取程序员记住自己是用什么方式写的然后在用BinaryReader读取时指定好匹配的编码方式就可以将原来的数据还原了。 你当初写进去的是int型就用BinaryReader.ReadInt32()来读取。 例如刚才写进去的100可以这样读取 class Program{static void Main(string[] args){ FileStream fs File.Open(E:\\MyFile.txt, FileMode.Open, FileAccess.Read);BinaryReader br new BinaryReader(fs);int a br.ReadInt32(); }} 这样a就等于100了 另外的例子 BinaryWriter bw new BinaryWriter(fs, Encoding.UTF32);bw.Write(a);输出为61 00 00 00占4字节这就是字符a用UTF32格式编码的结果。 读取这个输出 BinaryReader br new BinaryReader(fs, Encoding.UTF32);Console.WriteLine(br.ReadChar()); BinaryWriter bw new BinaryWriter(fs, Encoding.ASCII);bw.Write(a);输出为61占1字节这就是字符a用ACSII格式编码的结果。读取这个输出 BinaryReader br new BinaryReader(fs, Encoding.ASCII);Console.WriteLine(br.ReadChar());文件的本质 所谓的.txt文件本质不过是硬盘上一堆二进制数据而已。 往文件中写文本就是把文本所对应的编码(也就是数字)写进txt文件。 当你用记事本打开一个txt就是使用“记事本”这个程序对这堆二进制数据进行解释。 比方说记事本在txt中读到了一个64H然后记事本去ASCII字库里查询64H代表什么字符查到它代表‘d’于是记事本就负责把‘d’这个字符给显示出来。其实文件里存的不是‘d’而是‘d’的ASCII编码。 但问题是世界上存在多种编码方式也就对应了不同的字库比如GBK 比如Big5 比如Unicode同样的编码在不同的字库中对应了不同的字。所以记事本对二进制数据进行解释的时候需要知道这些数据使用什么方式编码才能去对应的字库查它是哪个字。所以文件头有时候会有一些标识数据用来提示记事本这个txt是用什么方式编码。 比如文件头的FF FE意味着本文用Unicode格式编码。而FE FF意味着用BigEndianUnicode方式。所以FF FE 8B 73 被解释为王 FE FF 8B 73被解释为‘譳’。 我们新建一个文本文档输入王然后查看其16进制的数据发现文档数据为CD F5。这是默认编码格式下的王的编码。 然后将该文本文档另存为Unicode格式的发现其16进制数据变成了FF FE 8B 73。 再另存为Unicode big endin之后16进制数据变为FE FF 73 8B。 这些底层数据的变化过程是由记事本程序来维护的但无论底层数据怎么变动我们看到的文本都是不变的。记事本程序并负责格式转换并保证只改变编码方式而不改变文本。 出现乱码就是对二进制数据进行了错误的解释。 向文件中写入字符数据时 当用于写字符的时候StreamWriter和BinaryWriter是差不多的。二者稍有区别。 看下面的例子 FileStream fs File.Open(E:\\MyFile.txt, FileMode.OpenOrCreate, FileAccess.Write);StreamWriter sw new StreamWriter(fs, Encoding.Unicode);
sw.Write(‘王’);
MyFile.txt内容为FF FE 8B 73StreamWriter sw new StreamWriter(fs, Encoding.BigEndianUnicode);
sw.Write(‘王’);
MyFile.txt内容为FE FF 73 8B BinaryWriter bw new BinaryWriter(fs, Encoding.Unicode);
bw.Write(‘王’);
MyFile.txt内容为8B 73BinaryWriter bw new BinaryWriter(fs, Encoding.BigEndianUnicode);
bw.Write(‘王’);
MyFile.txt内容为73 8B 当新建的时候StreamWriter会顺便写入FF FE这样的标识数据而BinaryWriter不会写入任何表示数据只把王的编码写入文件。 当append的时候StreamReader设定的编码方式是不会改变文档原有的编码方式的。 举例来说。 有一个空的Unicode格式的MyFile.txt该txt文件中只有两个字节的数据FF FE。 执行如下代码 FileStream fs File.Open(E:\\MyFile.txt, FileMode.Append, FileAccess.Write); StreamWriter sw new StreamWriter(fs); sw.Write(王); 执行之后MyFile.txt内的数据为FF FE E7 8E 8B 其中E7 8E 8B是StreamWriter采用默认编码格式对王进行编码的结果。 当记事本程序试图将FF FE E7 8E 8B解释成文本时遇到FF FE会认为这是Unicode编码于是把后边的所有数据都按照Unicode的格式解释于是E7 8E 8B被解释成了乱码。把FF FE 改成00 00 之后记事本找不到FF FE于是就把这一坨数据按照默认方式解释这就正确地将E7 8E 8B解释成了‘王’字。