好久没有动笔写博客了,这个小天地被我闲置的放了好久好久,接下来要慢慢捡起来了。
备注:通过C#的StreamWriter类输出一个TXT流文件,供下位机工程师使用,发现打开的16进制文件中,默认添加了EF BB BF前缀。
1 public int SaveZAbnormalScrollbaskTxt(string strTargetPath) 2 { 3 try 4 { 5 string strBufferLine = ""; 6 string expressionString = null; 7 int nNumber = 0; 8 DataRow dr; 9 StreamWriter streamWriter = new StreamWriter(strTargetPath, false,Encoding.UTF8); 10 for (int i = 0; i < dbZStressAbnormalStatistics.Rows.Count; i++) 11 { 12 dr = dbZStressAbnormalStatistics.Rows[i]; 13 14 //从特征点表中取到经纬度方向,距离等值。 15 if (Convert.ToString(dr[4]) == "" && String.IsNullOrEmpty(Convert.ToString(dr[4]))) 16 continue; 17 18 var gpsDr = GetGpsPointRow(dr[2].ToString(), dr[1].ToString()); 19 if (gpsDr == null) 20 continue; 21 22 strBufferLine = "00" + (++nNumber) + "," + dr[2] + "," + gpsDr[3] + "," + dr[1] + "," + gpsDr[5] + "," + gpsDr[6] + 23 "," + gpsDr[1] + "," + dr[7] + ",X"; 24 if (strBufferLine.Length<64) 25 { 26 for (int j = strBufferLine.Length; j < 62; j++) 27 { 28 strBufferLine +=" "; 29 } 30 strBufferLine += " "; 31 } 32 var ab = strBufferLine.Length; 33 streamWriter.Write(strBufferLine); 34 } 35 streamWriter.Close(); 36 streamWriter.Dispose(); 37 return 100; 38 } 39 catch (Exception ex) 40 { 41 throw new Exception(ex.Message); 42 } 43 }
代码中默认是以UTF-8格式输出保存的,通过记事本和NotPadd++打开都没有问题,但只要以16进制打开就会显示默认的EF BB BF格式前缀。
经查验,发现windows电脑在使用过程中,会将文件默认添加EF BB BF前缀,网上给出的解答说是转换为GB2312这种中国编码制定的格式就可以。
1 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来标记文本文件的编码方式的。