JAVA網路傳輸亂碼問題
轉自:http://1035054540-qq-com.iteye.com/blog/1856060
JAVA編解碼
---- 亂碼問題
---- 通過一個事例進行分析
一、需求:
二、過程分析:
第一步:java檔案編碼格式
檔案格式非固定:
第二步:java檔案編寫儲存
第三步:編譯成Class檔案
第四步:load class檔案到JVM
第五步:記憶體
1、java檔案中的字串
2、執行時從網路中讀取到記憶體中的字串
3、執行時從本地檔案中讀取到記憶體中的字串
4、執行時將記憶體中的字串寫入到檔案中
通過一個事例進行分析:
一、需求:
IDE:
Myeclipse 10.0
需求:
編寫一個java檔案,用來讀取網路資源、本地檔案a以及java檔案中的字串。然後輸出讀取的字串到檔案b.txt中。
二、過程分析:
第一步:java檔案編碼格式
檔案格式非固定:
Java檔案在編寫之前需要指定檔案的編碼格式,預設編碼和當前作業系統平臺編碼保持一致。比如,當前作業系統平臺為windows中文版,那麼編碼一般為GBK。當然可以對儲存檔案的編碼進行修改。例如修改成UTF-8。那麼此時檔案儲存的編碼就為UTF-8。
第二步:java檔案編寫儲存
該java檔案中,有讀取網路流的方法、讀取本地檔案的方法及其輸出字串到檔案中的方法;編寫完成之後,那麼則以第一步的編碼進行儲存。另外,當前java檔案中的所有字串則以第一步中的編碼得以儲存。比如說當前java檔案中有 String str=”abc中國”;第一步的編碼設定為UTF-8,那麼則以UTF-8進行儲存。如果是GBK,那麼則以GBK進行儲存。
第三步:編譯成Class
編譯後的class檔案的編碼固定為UTF-8;和java檔案編碼格式無關。說明,編譯器在編譯的過程中將檔案格式做了處理。編譯器的這種處理操作不會帶來亂碼問題,因為我們必須要相信編譯器的編解碼處理過程。
第四步:Load class 檔案到jvm
jvm中的所有字串編碼都為unicode。所以的話,從class檔案再到jvm。編碼又做了一次處理。同樣也必須相信這種處理不會為亂碼留下伏筆;
第五步:記憶體
記憶體中執行的是jvm中的資料,jvm中的資料編碼為unicode。那麼記憶體中同樣也以unicode方式進行儲存。但是有一個問題,記憶體執行的過程中,可能會設計到讀取檔案內容、網路內容以及輸出這些內容的操作。在記憶體中讀取的網路內容、檔案內容會以不同的編碼出現。這種編碼和java檔案中處理的方式有關。這兒是亂碼問題出現原因的一部分。記憶體中還有輸出字串內容到檔案的操作。這兒也會存在問題。
詳細來看:
1、java檔案中的字串
Java程式碼- String abc = "abc中國";
- byte[] bytes = abc.getBytes();
- for (byte b : bytes) {
- System.out.print(b+" ");
- }
- System.out.println();
- String newabc=new String(abc);
- System.out.println(newabc);
- Java檔案編碼為UTF-8:
- 列印結果:
- 97 98 99 -28 -72 -83 -27 -101 -67
- abc中國
- Java檔案編碼為GBK:
- 列印結果:
- 97 98 99 -42 -48 -71 -6
- abc中國
- 注:java檔案的編碼可以通過選擇java檔案右鍵Properties——》Text file encoding 中進行設定
出現上面列印結果的原因分析如下;
假如當前java檔案的編碼是gbk,那麼"abc中國"則以gbk格式進行儲存。
abc.getBytes() 方法將字串轉換成位元組處理方式是以當前平臺的編碼進行處理,而在選擇java檔案右鍵Properties——》Text file encoding 中進行設定的編碼就是此時java檔案平臺的編碼。
abc.getBytes() 的本質是 abc.getBytes(“ Charset.defaultCharset()”) ;
它們兩者是等效的 。因為我們當前的編碼設定為gbk,那麼就等效於abc.getBytes(“gbk”)。也就是說abc.getBytes()等價於abc.getBytes(“gbk”);
同樣值得注意的是String newabc=new String(bytes); 這兒也進行了預設操作處理。String newabc=new String(bytes) 等效於String newabc=new String(bytes,Charset.defaultCharset()) 因為當前編碼是gbk則
String newabc=new String(bytes) 等效於 String newabc=new String(bytes,’gbk’)
理一下思路:
abc中國 以gbk編碼儲存——》以utf-8 編碼的class檔案存在——》以unicode編碼load於jvm中——》同樣以unicode的形式存在於記憶體中——》再以gbk編碼轉成位元組——》最後以gbk編碼轉成字串;
因為最後兩步字串轉成位元組和位元組轉成字串的編碼是統一的,都為gbk。所以不會有亂碼的產生。亂碼產生的原因就是最後兩步字串的編解碼是不統一的。假如字串變成位元組的過程採用gbk編碼,而最後位元組變成字串以utf-8的形式編碼。那麼肯定會出亂碼問題。下面事例就是:
ReadJavaString.java
Java程式碼- String abc = "abc中國";
- byte[] bytes = abc.getBytes("gbk");
- for (byte b : bytes) {
- System.out.print(b+" ");
- }
- System.out.println();
- String newabc=new String(abc,"utf-8");
- System.out.println(newabc);
- 列印結果如下:
- 97 98 99 -42 -48 -71 -6
- abc?й?
結論:避免亂碼出現問題的解決辦法就是統一編碼。
字串——位元組 位元組——字串 用同一種編碼
2、執行時從網路中讀取到記憶體中的字串
假如需求為:在遠端伺服器中儲存著一個編碼為gbk的 wsx.txt 檔案,要將wsx.txt 檔案中的內容讀取到本地進行列印或者儲存。wsx.txt 中的內容為abc中
ReadResourceFromNetWork.java
Java程式碼- URL url =null;
- try {
- url = new URL("http://wangshuxiong.jhost.cn/wsx.txt");
- URLConnection urlconnection = url.openConnection();
- InputStream ins = urlconnection.getInputStream();
- int a=0;
- while ((a = ins.read()) != -1) {
- System.out.print(a+" ");
- }
- ins.close();
- } catch (Exception e) { }
- 列印結果:97 98 99 214 208
- 此時當前ReadResourceFromNetWork.java 檔案的編碼為gbk。改變ReadResourceFromNetWork.java 的編碼為utf-8 的時候,我們發現一個現象。列印結果依舊為 : 97 98 99 214 208
- 當我們改變wsx.txt 的編碼為utf-8 ,內容依舊為“abc中” 不論ReadResourceFromNetWork.java檔案的編碼是utf-8 還是gbk,那麼列印結果都為:
- 97 98 99 228 184 173
- } catch (Exception e) { }
- 由此我們得出一個結論:
- 從網路中讀取資原始檔的時候,無論當前java檔案編碼為何值,我們最後得到的一個個位元組只與讀取的資原始檔儲存的編碼有關。
- 那麼我們可以知道的是:下面wsx.txt 編碼為utf-8 的時候,那麼讀取的位元組陣列bytes 中的編碼為utf-8;
- URL url =null;
- try {
- url = new URL("http://wangshuxiong.jhost.cn/wsx.txt");
- URLConnection urlconnection = url.openConnection();
- InputStream ins = urlconnection.getInputStream();
- byte[] bytes=new byte[ins.available()];
- int len= ins.read(bytes); /*返回的len是儲存到bytes陣列中實際的長度,比如說bytes陣列定義長度為1024,但是隻讀取了100個位元組長度,那麼則返回的len為100,len最大值為bytes陣列初始長度*/
- ins.close();
- 當前ReadResourceFromNetWork.java編碼為gbk的時候;呼叫下面方法的話肯定會是亂碼,前面說過,String newabc=new String(bytes) 等效於String newabc=new String(bytes,Charset.defaultCharset());即為GBK編碼,兩者編碼不統一,亂碼是必然,列印結果如下: abc涓?
要解決上面亂碼問題,方法很簡單,不是說兩者統一就行了嘛。既然讀取位元組的時候無法改變位元組讀取的編碼,事實上也是萬萬不能改變的。那麼我們就改變位元組變成字串時候的編碼
String newabc=new String(bytes,“utf-8”);
列印結果如下:
abc中 。
小結一下:
對於讀取網路資源亂碼問題,如果能夠知道資源的編碼格式,那麼,只需要在轉成字串的過程中使用這種編碼就行。所以,關鍵問題落在了判斷資原始檔編碼方式是那種。
有些檔案是由BOM(byte order mark 位元組序標記)的,那麼我們只需要判斷檔案的BOM 就行。 比如說UTF-8 的BOM 是前三個位元組為:-17、-69、-65。GBK 則前兩個位元組為 -1 -2。所以一個檔案含有ROM 的話,我們只需要判斷位元組序列標示就行。但是往往某些資原始檔是沒有位元組序列標示符的。所以,就得考慮其他的方式解決了。
先看一些補充知識:
Unicode是字符集,全世界所有通用存在的文字都有一個唯一的標示符。
它的編碼範圍是0000-FFFF 。兩個位元組
各個國家語言的編碼範圍參照如下:
中文的編碼範圍:4e00~9fff 大概有兩萬多個字。
Ascii的範圍為0-127 。
GBK編碼中,一個漢字用兩個位元組來標示,一個英文字元用一個位元組表示,說白了就 是ascii值。
前一個位元組十進位制的範圍是:128-254 ,第二個位元組十進位制範圍是64-254
UTF-8編碼中:一個漢字三個位元組標示
第一個位元組十進位制範圍: 224-255 ,第二、三個位元組十進位制 128-255
GBK 和 unicode的關係是存在一個鍵值對錶儲存gbk 十六進位制和unicode十六進位制的關係。然後通過unicode編碼和中文對照關係,則可以通過一個gbk編碼得到對應的中文漢字。
流程如下:
GBK-Unicode對應表 Unicode表
通過gbk——獲得unicode編碼值——通過unicode編碼值獲得中文漢字
UTF-8 和Unicode的轉換規則關係如下:
Unicode符號範圍(十六進位制) |
UTF-8編碼方式(二進位制) |
0000 - 007F |
0xxxxxxx |
0080 - 07FF |
110xxxxx 10xxxxxx |
0800 - FFFF |
1110xxxx 10xxxxxx 10xxxxxx |
因為中文的unicode範圍為:4e00~9fff。所以中文是以三個位元組來儲存的。X是unicode對應二進位制依次填充的
例如:Unicode 編碼FFFF 二進位制:1111 1111 1111 1111
填充的UTF-8 為:11101111 10111111 10111111
小結: gbk 與unicode之間的轉換是通過gbk unicode對映表。
Utf-8 與unicode之間的轉換是通過轉換規則公式
所以說,unicode是核心中介。Gbk要轉換成utf-8的話,先轉成unicode。然後unicode再轉換成utf-8;反之亦然。
繼續接著討論怎麼判斷讀取資原始檔格式的問題:
1、當讀取的位元組在0-127範圍的話,說明是ascii字元。直接通過 char c=(char) ?轉換就行;
2、如果位元組 大於127 ,那麼則判斷位元組是不是在128到224範圍內,如果是的話,說明是GBK編碼。因為utf-8的第一個位元組範圍是224到255範圍內的。
3、如果不在128到224範圍內,接著判斷第二個位元組,如果第二個位元組在64到128範圍內的話,那麼則為GBK 編碼。因為UTF-8 的第二三個位元組範圍是128--255.獲取這兩個位元組,轉成十六進位制,再通過gbk unicode對映表就可以得到unicode值,再通過unicode值就可以得到中文漢字。
4、如果第二個位元組依舊不在64到128範圍內。那麼則判斷第三個位元組。如果第三個位元組在0--127範圍的話,說明前兩個位元組為gbk編碼。因為gbk編碼是兩個位元組。
5、如果第三個位元組大於127的話,說明這三個位元組為utf-8編碼。然後通過utf-8 與unicode的轉碼規則公式換算成unicode,然後通過unicode得到中文漢字。
3、執行時從本地檔案中讀取到記憶體中的字串
和網路中讀取的結果完全一樣,參考其上!
轉自:http://1035054540-qq-com.iteye.com/blog/1856060
JAVA編解碼
---- 亂碼問題
---- 通過一個事例進行分析
一、需求:
二、過程分析:
第一
1.需求:後臺使用java編碼,傳遞到前臺使用js接收解碼
解決:
1)後臺:json字串形式傳遞
①簡單的java物件轉化成jsonObject,再toString()
JSONObject rtObject = new JSONObject();rtObject.p
在傳送mq時,傳入資料正常,但是消費者接收的資料是亂碼的,可以在傳送的時候對資料進行編碼,然後消費者在進行解碼即可
java中編碼:URLEncoder.encode(URLEncoder.encode("傳遞的中文","utf-8")); java中解碼碼:URLDecoder.decode(
一、解決亂碼問題,要先了解一些基礎概念:
1、字符集:在計算機底層中資料儲存的都是二進位制資料,要想獲取真正有意義的字元,就必須讓二進位制資料與每一個字元對應起來,這種對應關係就形成了一張編碼表。
常用字符集: iso-8859-1 拉丁碼錶 latin,
為什麼要進行網路加密?
下面來說一下我的實現思想:
加密:
1、第一個假資料長度n+n個隨機字串+真實資料的位元組流+真實資料MD5加密後的串+長度位m第二個假資料+第二個家資料的長度m
2、上述資料在進行跟字母t的按位異或
例項:
816249737104
post 中文亂碼解決方式
接受資料的時候設定
request.setCharacterEncoding("utf-8");//編碼必須和頁面編碼一致
頁面設定
<%@page import="java.net.URLDecoder"%>
<%@page
Netty流資料的傳輸處理
Socket Buffer的缺陷
對於例如TCP/IP這種基於流的傳輸協議實現,接收到的資料會被儲存在socket的接受緩衝區內。不幸的是,這種基於流的傳輸緩衝區並不是一個包佇列,而是一個位元組佇列。這意味著,即使
今天,翻書的時候看到書上的網路傳輸資料的時候,頓時感覺之前的自己的操作太low了,這篇主要講,在網路傳輸的過程中,你傳送請求,但是你現在介面又需要根據返回的資料來更新介面,但資料什麼時候返回你又不知道,這時候該怎麼辦?之前我直接在主執行緒裡面一個死迴圈判斷接受資
MD5和RSA是網路傳輸中最常用的兩個演算法,瞭解這兩個演算法原理後就能大致知道加密是怎麼一回事了。但這兩種演算法使用環境有差異,剛好互補。一、MD5演算法首先MD5是不可逆的,只能加密而不能解密。比如明文是yanzi1225627,得到MD5加密後的字串是:14F2AE15
在網路程式設計中的TCP傳輸裡,拿到Socket的源後,應該怎麼進行讀寫操作呢,下面我列舉了兩種方法,希望大家幫忙補充····
1.利用byte陣列作為一個緩衝區進行讀寫
客戶端上傳
1 //獲取
傳輸層概述作用:傳輸層為它上面的應用層提供通訊服務。在OSI七層參考模型中,傳輸層是面向通訊的最高層,也是使用者功能的最底層。傳輸層兩大重要的功能:複用 和 分用。 複用:在傳送端,多個應用程序公用一個傳輸層;分用:在接收端,傳輸層會根據埠號將資料分派給不同的應用程序。和網路 ont character delete bsp mage gbk net utf-8 type 一:html亂碼或者引入的JS亂碼 1:第一步,text file encoding 首先確保文件的保存格式要UTF-8,如在eclipse中,要在文件上點屬性,確保這裏選擇U window servlet out efault system ava main函數 set print 在servlet中向控制臺輸出中文亂碼;
但是在servlet裏的main函數輸出,中文是正確的;
通過在main函數裏加了一段
System.out.print res utf 同時 訪問 文件的 redirect article nco 16px 參考:http://www.cnblogs.com/haimishasha/p/6117968.html (關於JAVA字符編碼:Unicode,ISO-8859-1,GBK,UTF- title 查詢 發現 即使 art 操作 https size tro 現象: cenos 部署java web 程序 ,java類中有中文 出現亂碼現象
即使使用:
System.getProperty("中文")
控制臺都出現 ??????
轉載地址:http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html
代理(Proxy): 一箇中間程式,它可以充當一個伺服器,也可以充當一個客戶機,為其它客戶機建立請求。請求是通過可能的翻譯在內部或經過傳遞到其它的
什麼是Socket
Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。
如下
理解java的BIO、NIO、AIO的原理:
一、UNIX程式設計中的五種IO模型:
1. 阻塞IO
外賣小哥去商家取外賣,到了麻辣燙店,商家還沒做好,
外賣小哥雖然還有其他單子要送,但是不得不焦急地等著商家;
2. 非阻塞IO
外賣小哥去商家取外賣 UDP(User Datagram Protocol):
基於Intenet IP協議(複用/分用、簡單的錯誤校驗)
儘可能的服務(可能丟失、亂序到達)
無連線(不需要握手、每個UDP段獨立於其他)
常用於流媒體應用(容忍丟失、速率敏感)
UDP用於DNS、SNMP
UDP上實現可靠資料傳輸:
最近在GitHub上看程式碼偶然發現了使輸入經過網路傳輸後的輸出,即“embedding”視覺化的小細節,在此寫下來加深記憶:
Git原連結:https://github.com/ywpkwon/siamese_tf_mnist
首先是建立網路(Siamese 網路):
import t 相關推薦
JAVA網路傳輸亂碼問題
java網路傳輸字元編碼亂碼解決
java資料傳輸時中文亂碼
網路傳輸中文亂碼問題
JAVA網路資訊傳輸加密演算法
java 頁面傳輸中文亂碼解決方案
java網路程式設計之Netty流資料的傳輸處理(五)
Java在進行網路傳輸的過程中的奇技淫巧
Android網路傳輸中必用的兩個加密演算法:MD5 和 RSA (附java完成測試程式碼)
java網路程式設計TCP傳輸—流操作—拿到源後的寫入動作
java面試-計算機網路傳輸層知識點全覆蓋
JAVA開發中文亂碼的幾個解決方案
java servlet 中文亂碼
java Web 中文亂碼
centos java tomcat 中文亂碼解決辦法
網路傳輸的中介:代理、閘道器、通道
Java 網路IO程式設計
java網路程式設計_IO模型
計算機網路——傳輸層
tensorflow 中資料經過網路傳輸後的embedding視覺化方法例項: