最近項目設計到java項目與c項目基於tcp通訊的數據交互,在發送數據的過程當中由java發送數據給c項目,出現了亂碼,完全學習了下字符串編碼與文件編碼之間的關係,關於編碼的什麼ASCII、UTF-8(Unicode的一種實現)、GBK之間的關係網上一搜一籮筐,不在詳細闡述,能夠參看這裏。html
每一個項目都有工程編碼,java工程能夠項目->屬性(properties)查看其編碼,而咱們在寫c項目的時候好像歷來都沒有注意這些。在vs2010默認的是ANSI(即GBK)的,CodeBlock默認的也是GBK。咱們先來看下c項目字符串的編碼與文件編碼的關係。java
使用CodeBlock建了兩個c項目,一個編碼是GBK的,一個是UTF-8,(CodeBlock項目編碼設置setting->editor->other setting),使用相同的代碼tcp
int main()
{
int i = 0;
char* str = "中文";
while(str[i++] != '\0')
{
printf("%0x\n",str[i]&0xFF);
}
printf("%s", str);
return 0;
}學習
打印"中文"在內存中的編碼,在UTF的c項目中輸出結果爲:,用二進制文件查看其.c和.exe文件編碼編碼
能夠看到.exe文件和.c中char* str都是UTF-8編碼,與輸出的字符串編碼是一致的。spa
再來看GBK的c項目中的輸出狀況:,文件.c、.exe二進制編碼狀況:操作系統
那麼能夠確定:在c項目中,字符串的編碼char* str與文件.c的編碼是一致的,而文件的編碼通常默認與項目編碼一致。這裏有必要就UTF-8項目輸出的是亂碼進行解釋,由於win操做系統環境是中文GBK的,控制檯默認輸出的是GBK,因此當輸出UTF-8的字符串時就出現了亂碼。設計
----------------------------------------------------------------java分割線-------------------------------------------------------------------------------------------------------------------------3d
再來看java項目中.class與.java文件之間的編碼關係,咱們先建一個GBK的java項目,代碼以下:code
import java.io.UnsupportedEncodingException;
public class test {
public static void main(String[] args) {
String str = "中文";
try {
byte[] bs = str.getBytes("GBK");
for(int i = 0; i < bs.length; i++){
System.out.println(Integer.toHexString(bs[i]));
}
String str2 = new String(bs,"GBK");
System.out.println(str2);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
java對字符串的編碼處理支持就好的多了,你能夠獲取任何本身想要字符編碼,並指定其輸出編碼(通常編碼用什麼,解碼就用什麼)。在GBK的項目中.java文件用的是ANSI的存儲方式,.class文件是以何種編碼呢?GBK嗎?,咱們來看下.java和.class文件的二進制:
String str在.java文件中是GBK存儲,可是生成的二進制.class文件其編碼倒是UTF-8的!!!也就是咱們說的java採用的是Unicode編碼,在生成.class文件的時候編譯器幫咱們把各類不一樣編碼的.java文件所有生成統一的Unicode編碼的.class文件,那麼在java平臺全部字符在內存中的表示都是統一的(無論你的項目是什麼編碼,字符串內存表示都同樣,與項目編碼無關)。
至於UTF-8的java項目其.java和.class必定都是同樣的編碼。