我們的服務器為linux系統,日志中的字段通常會用不同分隔符來做分隔,在不同操作系統編碼格式下查看也會有不同的體現,甚至會出現所謂的亂碼。我在xshell5下常用的編碼格式Unicode(UTF-8)和默認語言。通常xshell5的默認語言能查看到分隔符隔開的字段,而utf-8不能。在網上查了下\001作為分隔符的日志,從linux終端復制出來用notePad打開時看到的SOH,而\002分隔的,從終端復制到編輯器是里STX。。。
比如下案例:
一 java代碼: public class appendTest { public static void main(String[] args) { String string1 = "HOW"; String string2 = "DO"; String string3 = "YOU"; String string4 = "DO"; StringBuffer clickBuffer = new StringBuffer(); clickBuffer.append(string1).append("\001").append(string2).append("\002").append(string3).append("\003").append(string4); System.out.println(clickBuffer); } }
二 放到linux下編譯運行:javac appendTest.java;java appendTest.查看結果
默認語言時:linux下顯示為--,復制到notePad++中,顯示為
unicode時:HOWDOYOUDO。
java代碼中:會寫成"\001" "\002",或者任意其他字符,作為分隔。
我在查看日志時,大多從linux終端(默認語言下)復制到notePad++里,再用編輯器的替換功能,按分隔符換行,對比各個字段。如需調用接口進行插入,則在notepad++里將分隔符替換成"\001"之類寫入時的分隔符,進行寫入。
下面是網上找的一些資料,不過並不是我想要的,后續再熟悉熟悉看。
1 ASCII碼
在計算機內部,所有的信息最終都表示為一個二進制的字符串,每一個二進制位(bit)有0和1兩種狀態,因此八個二進制就可以組合出2的8次方=256種狀態,被稱為一個字節(byte),即,一個字節可以用來表示256種不同的狀態,從00000000到11111111。上個世紀60年代,美國指定了一套字符編碼,對英語字符和二進制位之間的關系,做了統一規定。被稱為ASCII碼。ASCII一共規定了128個字符的編碼,占用一個字節的后7位,最前面的1位統一規定為0。比如空格"SPACE"是32,即00100000.
英語用128個符號編碼就夠了,但是其他語言,128個符號並不能滿足需求。另不同的國家有不同的字母。哪怕他們都是用256個符號的編碼方式,代表的字母卻不一樣。因此編碼格式是多種多樣的。
2 Unicode
世家上存在如此多的編碼方式,同一個二進制數字便可被解釋成不同的符號。因為打開文件必須知道它的編碼方式,否則用錯誤的方式解讀,就會出現亂碼。為什么電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。
可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那么亂碼問題就會消失。這就是Unicode,就像它的名字都表示的,這是一種所有符號的編碼。Unicode當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字"嚴"。具體的符號對應表,可以查詢unicode.org,或者專門的漢字對應表。
然后Unicode也有它自己的問題,它只是一個符號集,只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。比如漢字"嚴"的unicode是十六進制數4E25,轉成二進制足足有15位 100111000100101,也就是說這個符號的表示至少需要2個字節。表示其他更大的符號,可能需要3個字節或者4個字節,甚至更多。
這里就有兩個嚴重的問題,第一個問題是,如何才能區別Unicode和ASCII?計算機怎么知道三個字節表示一個符號,而不是分別表示三個符號呢?第二個問題是,英文字母只用一個字節表示就夠了,如果Unicode統一規定,每個符號用三個或四個字節表示,那么每個英文字母前面必然有幾個字節是0,對於存儲來說,文本文件的大小會因此大出二三倍,這是無法接受的。他們造成的結果是:1)出現了Unicode的多種存儲方式,也就是說有許多不同的二進制格式,可以用來表示Unicode;2)Unicode在很長的一段時間內無法推廣,直到互聯網出現。
3.UTF-8
互聯網的普及,強烈要求出現一種統一的編碼方式。UTF-8就是在互聯網上使用最廣的一種Unicode的實現方式。其他實現方式還包括UTF-16(字符用兩個字節或四個字節表示)和UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重復一遍,這里的關系是,UTF-8是Unicode的實現方式之一。
UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。
UTF-8的編碼規則很簡單,只有二條:
1)對於單字節的符號,字節的第一位設為0,后面7位為這個符號的unicode碼。因此對於英語字母,UTF-8編碼和ASCII碼是相同的。
2)對於n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。
解讀UTF-8編碼非常簡單。如果一個字節的第一位是0,則這個字節單獨就是一個字符;如果第一位是1,則連續有多少個1,就表示當前字符占用多少個字節。
ASCII編碼-控制字符
二進制 | 十進制 | 十六進制 | 控制字符 | 轉義字符 | 說明 |
---|---|---|---|---|---|
000 0000 | 0 | 00 | NUL | Null character(空字符) | |
000 0001 | 1 | 01 | SOH | Start of Header(標題開始) | |
000 0010 | 2 | 02 | STX | Start of Text(正文開始) | |
000 0011 | 3 | 03 | ETX | End of Text(正文結束) | |
000 0100 | 4 | 04 | EOT | End of Transmission(傳輸結束) | |
000 0101 | 5 | 05 | ENQ | Enquiry(請求) | |
000 0110 | 6 | 06 | ACK | Acknowledgment(收到通知) | |
000 0111 | 7 | 07 | BEL | a | Bell(響鈴) |
000 1000 | 8 | 08 | BS | b | Backspace(退格) |
000 1001 | 9 | 09 | HT | t | Horizontal Tab(水平制表符) |
000 1010 | 10 | 0A | LF | n | Line feed(換行鍵) |
000 1011 | 11 | 0B | VT | v | Vertical Tab(垂直制表符) |
000 1100 | 12 | 0C | FF | f | Form feed(換頁鍵) |
000 1101 | 13 | 0D | CR | r | Carriage return(回車鍵) |
000 1110 | 14 | 0E | SO | Shift Out(不用切換) | |
000 1111 | 15 | 0F | SI | Shift In(啟用切換) | |
001 0000 | 16 | 10 | DLE | Data Link Escape(數據鏈路轉義) | |
001 0001 | 17 | 11 | DC1 | Device Control 1(設備控制1) | |
001 0010 | 18 | 12 | DC2 | Device Control 2(設備控制2) | |
001 0011 | 19 | 13 | DC3 | Device Control 3(設備控制3) | |
001 0100 | 20 | 14 | DC4 | Device Control 4(設備控制4) | |
001 0101 | 21 | 15 | NAK | Negative Acknowledgement(拒絕接收) | |
001 0110 | 22 | 16 | SYN | Synchronous Idle(同步空閑) | |
001 0111 | 23 | 17 | ETB | End of Trans the Block(傳輸塊結束) | |
001 1000 | 24 | 18 | CAN | Cancel(取消) | |
001 1001 | 25 | 19 | EM | End of Medium(介質中斷) | |
001 1010 | 26 | 1A | SUB | Substitute(替補) | |
001 1011 | 27 | 1B | ESC | e | Escape(溢出) |
001 1100 | 28 | 1C | FS | File Separator(文件分割符) | |
001 1101 | 29 | 1D | GS | Group Separator(分組符) | |
001 1110 | 30 | 1E | RS | Record Separator(記錄分離符) | |
001 1111 | 31 | 1F | US | Unit Separator(單元分隔符) |