ANSI/UTF-8/UCS2(UTF-16),以及回车换行
最近遇到一個linux 平臺上invisible character (0x1d)引起的數(shù)據(jù)裝載失敗問題,正好借此機會整理一下字符編碼的相關(guān)知識。
?
回車/換行:
=================
顧名思義,回車和換行是兩個不同的控制字符:
??? -回車(Carriage Return)即\r,ascii碼13(0x0d),作用是將光標移到一行的開始位置
??? - 換行(LineFeed)即\n,ascii碼10(0x0a),作用是將光標移到下一行
在不同的操作系統(tǒng)平臺上,默認是用不同的控制符來標志一行的結(jié)束:
??? -Windows: \r\n
??? -Linux/Unix: \n
??? - Mac: \r(據(jù)說近來也改成了\n)
這種不同實現(xiàn)導致的結(jié)果就是Winodws上的標準文本文件在其它平臺上會多出一個^M控制符,而其它平臺的文件在Windows上看會只有一行。Linux上有dos2unix/unix2dos命令來解決文本換行的問題。
?
字符編碼:
=================
文字是人類的語言,對于計算機來講,語言就是0和1而已,因此將字符保存在計算機里就會涉及到字符編碼的問題。網(wǎng)上有許多文章和博客介紹不同字符編碼方式,這里就不引用了。列一些我自己理解的重點:
ASCII:ANSI
最初的計算機存儲有限,字符的存儲使用的是8位的ASCII碼(最高位為0),最多可以存儲128個字符,加上擴展ASCII碼(最高位為1)也只能存儲256個字符。于是,各國都制定了自己的兼容ascii編碼規(guī)范,就是各種ANSI碼,來表示不同的語言中的不同文字。于是同樣的ASCII碼在不同的字符集(Collation/CharSet/CodePage)上就可以表示不同的字符,這就是為什么ANSI字符一定要與特定的Collation綁定才能表示唯一正確的字符,綁定錯了就可能出現(xiàn)亂碼(ascii碼小于128的字符不會亂碼)。
?
Unicode
又名萬國碼,所有語言的所有字符都可以用唯一的Unicode碼來標識。Unicode有幾種不同的實現(xiàn)方式:
??? - UTF-8:按照字節(jié)(8位)來存儲編碼,長度可變(1~6字節(jié))。完全兼容ascii碼,即標準ascii碼中的字符在unicode中也是以相同的碼來表示的。UTF-8使用第一個字節(jié)確定字節(jié)數(shù):第一個字節(jié)首為0即一個字節(jié),110即2字節(jié),1110即3字節(jié),字符后續(xù)字節(jié)都用10開始。
???- UTF-16 (UCS2):按照雙字節(jié)存儲字符,因此有字節(jié)序問題:即高位在前(Big Endian)還是低位在前(LittleEndian)。這個行為與CPU處理字節(jié)方式有關(guān),一般LittleEndian用得比較多。比如“漢”字,Unicode碼為0x6C49,按照Big Endian存儲就是6C49,LittleEndian則為496C。
?
如何區(qū)分不同編碼的文件:
用UltraEdit或者類似編輯器打開文本文件,切換到HexMode(ctrl + h),看文件頭:
???- 沒有任何特殊文件頭的,直接第一個字符就是文本內(nèi)容的,是ansi文件
???- 以BOM (Byte Order Mark) 開頭的是Unicode文件。BOM可以是0xFEFF(表示BigEndian)、0XFFFE(表示Little Endian)、或者0xEFBBBF (UTF-8)。
?
注意,在Windows上用Notepad保存一個UTF-8的文件,用UltraEdit查看也可能以0xFFFE開頭,這是因為UltraEdit可能自動將UTF-8的文件轉(zhuǎn)換成UTF-16格式。如果通過UltraEdit打開文件查看BOM來確定文件格式,并不是安全的。UltraEdit下方狀態(tài)欄則真實的顯示了當前打開文件的實際編碼格式,而不是當前編輯的編碼格式。對于一個普通Ascii 格式的文件,它顯示為DOS或者UNIX,對于一個包含有UTF-8編碼字符的文件,它顯示為U8-DOS或者U8-UNIX,對于UTF-16編碼的文件,它顯示為U-DOS 或者U-UNIX。
?
我們知道,UTF-8 對于Ascii 字符的編碼與原有的Ascii 編碼一致,因此假如我們刪除了一個UTF-8DOS文件中所有Ascii 以外的字符,保存后再打開,UltraEdit 將顯示為DOS(Ascii)。
如果我們不希望UltraEdit 在打開UTF-8 文件時自動轉(zhuǎn)為UTF-16格式編輯,我們可以修改配置。如下圖,確保“自動檢測 UTF-8文件”不被選中。
需要注意的是,如果取消了這個選項,UltraEdit打開包含UTF-8編碼的文件會產(chǎn)生亂碼。
UltraEdit 在File-Convertions菜單中提供了多種編碼格式之間的轉(zhuǎn)換,這將影響到保存的文件編碼,轉(zhuǎn)換后,在狀態(tài)欄也能看到相應變化。在有些選項后標明有(UnicodeEditing) 或者(ASCII Editing),這指定了編輯時顯示用的編碼,并不影響保存文件所用的編碼,要區(qū)分開。
工具WinHex 可以用來查看文件16進制內(nèi)碼。
?
Unicode與SQL Server:
================
UTF-8是目前使用最廣泛的Unicode編碼格式,但是SQLServer使用的是UTF-16作為Unicode字符的編碼格式,即NCHAR/NTEXT/NVARHCAR存儲的都是雙字節(jié)編碼的Unicode字符,以N為前綴(比如N'Hello')的字符串即為雙字節(jié)Unicode字符。對于UTF-8字符串,如果它只包含ANSI字符,則可以按照ANSI串處理;否則的話必須將UTF-8串轉(zhuǎn)換成UTF-16、再交給SQLServer 處理。這種行為可能帶來兩個常見的問題:
???- 許多程序(包括ASP.NET)在輸出文件的時候都使用UTF-8格式。如果這些文件需要被SQLServer正確地處理,必須進行轉(zhuǎn)碼至UTF-16。
???- SQL 2005以后支持對NativeXML進行處理,但是如果XML文檔本身是UTF-8編碼,就沒辦法直接處理。下面是一個例子:
????在SSMS中運行如下代碼,會得到錯誤9420:
???DECLARE @InfXML??????
???SET????@Inf = '<?xml version="1.0"encoding="utf-8"?>
????????????????????<root>
???????????????????????<names>
????????????????????????????<name>張三</name>
????????????????????????</names>
????????????????????????<names>
????????????????????????????<name>李四</name>
????????????????????????</names>
????????????????????</root>
???????????????????'?
?????
???SELECT? x.value('name[1]', 'VARCHAR(10)') ASName?
???FROM???
轉(zhuǎn)載于:https://www.cnblogs.com/xieyuan/archive/2012/08/23/3787476.html
總結(jié)
以上是生活随笔為你收集整理的ANSI/UTF-8/UCS2(UTF-16),以及回车换行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fedora 安装QQ2012
- 下一篇: SQL Server中行列转换 Pivo