好久没有动笔写博客了,这个小天地被我闲置的放了好久好久,接下来要慢慢捡起来了。
备注:通过C#的StreamWriter类输出一个TXT流文件,供下位机工程师使用,发现打开的16进制文件中,默认添加了EF BB BF前缀。
public int SaveZAbnormalScrollbaskTxt(string strTargetPath) { try { string strBufferLine = ""; string expressionString = null; int nNumber = 0; DataRow dr; StreamWriter streamWriter = new StreamWriter(strTargetPath, false,Encoding.UTF8); for (int i = 0; i < dbZStressAbnormalStatistics.Rows.Count; i++) { dr = dbZStressAbnormalStatistics.Rows[i]; //从特征点表中取到经纬度方向,距离等值。 if (Convert.ToString(dr[4]) == "" && String.IsNullOrEmpty(Convert.ToString(dr[4]))) continue; var gpsDr = GetGpsPointRow(dr[2].ToString(), dr[1].ToString()); if (gpsDr == null) continue; strBufferLine = "00" + (++nNumber) + "," + dr[2] + "," + gpsDr[3] + "," + dr[1] + "," + gpsDr[5] + "," + gpsDr[6] + "," + gpsDr[1] + "," + dr[7] + ",X"; if (strBufferLine.Length<64) { for (int j = strBufferLine.Length; j < 62; j++) { strBufferLine +=" "; } strBufferLine += "\r\n"; } var ab = strBufferLine.Length; streamWriter.Write(strBufferLine); } streamWriter.Close(); streamWriter.Dispose(); return 100; } catch (Exception ex) { throw new Exception(ex.Message); } }
代码中默认是以UTF-8格式输出保存的,通过记事本和NotPadd++打开都没有问题,但只要以16进制打开就会显示默认的EF BB BF格式前缀。
经查验,发现windows电脑在使用过程中,会将文件默认添加EF BB BF前缀,网上给出的解答说是转换为GB2312这种中国编码制定的格式就可以。
StreamWriter streamWriter = new StreamWriter(strTargetPath, false,Encoding.GetEncoding("GB2312"));
试了试确实可以解决了我的问题。
既然找到问题的根源,那么就顺便记录下具体的原因吧。
Unicode规范中有一个BOM的概念。BOM——Byte Order Mark,就是字节序标记。在这里找到一段关于BOM的说明:
在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。
UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。
因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。