Java解析網路資料流的三種特殊方法
來源:互聯網
上載者:User
UTF8轉換成GB2312 當我們在基於HTTP協議的JSP或Servlet的應用中擷取資料或發送請求時,JVM會把輸送的資料編碼成UTF8格式。如果我們直接從HTTP流中提取中文資料,提取的結果為“????”(可能更多問號),為轉換成我們能夠理解的中文字元,我們需要把UTF8轉換成GB2312,藉助ISO-8859-1標準編碼能夠輕易的實現,下面的代碼實現了這一功能: byte [] b;String utf8_value; utf8_value = request.getParameter("NAME");//從HTTP流中取"NAME"的UTF8資料b = utf8_value.getBytes("8859_1"); //中間用ISO-8859-1過渡String name = new String(b, "GB2312"); //轉換成GB2312字元
在知道流長度的情況下將輸入資料流轉換成位元組數組 Java中的輸入資料流抽象類別InputStream有int read(byte[] b, int off, int len)方法,參數中byte[] b是用來存放從InputStream中讀取的資料,int off指定數組b的位移地址,也就是數組b的起始下標,int len指定需要讀取的長度,方法返回實際讀取的位元組數。剛學Java的朋友可能要說:先定義一個與流長度等長的位元組數組,調用read方法,指定起始下標為0,指定讀取長度與數組長度等長,不是一下子可以讀出來了嗎?說的沒錯,筆者曾經也試著這樣讀取資料,但後來發現在讀取網路資料時很不安全,我們想想在網路上擷取資料可能並沒那麼流暢,資料流的傳送可能會斷斷續續,所以並不能保證一次就能讀取全部資料,特別是在讀取大容量資料時更是如此,所以我們必須在讀取資料時檢測實際讀到的長度,如果沒有讀完已知長度的資料就應該再次讀取,以此迴圈檢測,直到實際讀取的長度累加與已知的長度相等,下面的代碼實現了這一功能:ServletInputStream inStream = request.getInputStream(); //取HTTP請求流int size = request.getContentLength(); //取HTTP請求流長度byte[] buffer = new byte[size]; //用於緩衝每次讀取的資料byte[] in_b = new byte[size]; //用於存放結果的數組int count = 0;int rbyte = 0;while (count < size) { //迴圈讀取rbyte = inStream.read(buffer); //每次實際讀取長度存於rbyte中for(int i=0;i<rbyte;i++) {in_b[count + i] = buffer[i];}count += rbyte;}或者代碼如下:int bytesRead=0;int byteToRead=1024;byte[] input=new byte[byteToRead];while(bytesRead<byteToRead){ bytesRead+=in.read(input,bytesRead,byteToRead-bytesRead);}
在不知道流長度的情況下將輸入資料流轉換成位元組數組 前面介紹了已知流長度的情況下的轉換方法,那麼當我們不知道流有多長時,也就是說不能確定轉換後的位元組數組有多大時,該怎麼處理呢?筆者查看了JDK文檔之後發現ByteArrayOutputStream有一個byte[] toByteArray()方法,該方法會自動建立一個位元組數組,然後返回。於是就巧妙的用ByteArrayOutputStream來作中間過渡實現轉換,其它處理跟上面所介紹已知長度的情況差不多。假設需要被轉換的流已經放在inStream裡了,我們可以用如下的代碼實現這一功能:ByteArrayOutputStream swapStream = new ByteArrayOutputStream();byte[] buff = new byte[100]; //buff用於存放迴圈讀取的臨時資料int rc = 0;while ((rc = inStream.read(buff, 0, 100)) > 0) {swapStream.write(buff, 0, rc);}byte[] in_b = swapStream.toByteArray(); //in_b為轉換之後的結果