1. 程式人生 > >JAVA初窺:字元編碼

JAVA初窺:字元編碼

參考書籍:《深入分析Java Web技術內幕(修訂版)》----許令波著
編碼問題一直在困擾著程式開發人員,這在Java中尤其突出,因為Java是跨平臺語言,字元在不同平臺之間進行傳輸時經常需要進行編碼切換。

為什麼要編碼?

眾所周知,計算機其實是很笨的,它只識別數字0和1,所以,無論什麼內容在計算機內最終都必須以01串的形式進行儲存,字元也不例外。在計算機中儲存資訊的最小單元是1個位元組,即8個bit,一個位元組所能表示的字元個數最多為256個(0~255,二進位制11111111=十進位制255)。但是,人類要表示的符號太多了,用一個位元組來表示顯然是遠遠不夠的,必須用更多的位元組來表示,比如:用兩個位元組最多可以表示65535個字元,用4個位元組表示的字元數可多達4294967295個。一個字元究竟應該用多少個位元組來表示才合適呢?這就是編碼所實現的功能,不同的編碼使用不同的位元組數或數值來表示字元。

常用編碼格式

ASCII碼

由於計算機是美國人發明的,因此,最早只有128個字母被編碼到計算機裡,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱為ASCII(American Standard Code for Information Interchange,美國資訊交換標準碼),採用一個位元組的低7位來表示,0~31是控制字元,如換行、回車、刪除等,32~127是列印字元,包括那些可以通過鍵盤輸入並且能夠顯示出來的字元,比如大寫字母、小寫字母、數字等。

ISO-8859-1

128個字元顯然是不夠用的,於是ISO組織在ASCII碼基礎上又制定了一系列標準來擴充套件ASCII編碼,它們是ISO-8859-1至ISO-8859-15,其中ISO-8859-1涵蓋了大多數西歐語言字元,所以應用得最廣泛。ISO-8859-1仍然是單位元組編碼,它總共能表示256個字元。

GB2312

如果要處理中文的話,一個位元組顯然還是不夠用,所以,中國製定了GB2312編碼,用來把中文編進去。GB2312是雙位元組編碼,總的編碼範圍是A1~F7,其中A1~A9是符號區,總共包含682個符號;B0~F7是漢字區,包含6763個漢字。

GBK

GBK全稱是《漢字內碼擴充套件規範》,是國家技術監督局為Windows 95所制定的新的漢字內碼規範,它的出現是為了擴充套件GB2312,並加入更多的漢字。它的編碼範圍是8140~FEFE(去掉XX7F),總共有23940個碼位,它能表示21003個漢字,它的編碼是和GB2312相容的,也就是說用GB2312編碼的漢字可以用GBK來解碼,並且不會有亂碼。

UTF-16

說到UTF-16必須提到Unicode(Universal Code 統一碼),全世界有上百種語言,日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr裡,如此,假如各國都按照各國各自的標準來設計編碼,在某些多語言混用的場景下,就會不可避免地出現編碼衝突。為了解決這一問題,ISO提出了Unicode標準,它試圖將世界上所有語言都統一到一套編碼裡。而實際上Unicode僅僅只是一個規範,它使用0~65535之間的數字來表示所有字元,其中0~127這128個數字表示的字元與ASCII完全一樣。至於要把0~65535這些數字以怎樣的形式轉換為01串儲存到計算機中,Unicode並未宣告其具體的實現方式,於是就出現了UTF(Unicode Transformation Format),包括:UTF-16和UTF-8。
UTF-16具體定義了Unicode字元在計算機中的存取方法,它用兩個位元組來表示Unicode的轉化格式,採用定長的表示方法,即不論什麼字元都用兩個位元組表示,兩個位元組就是16個bit,所以叫UTF-16。

UTF-8

UTF-16統一採用兩個位元組來表示一個字元,雖然在表示上非常簡單、方便,但是也有其缺點,有很大一部分字元用一個位元組就可以表示的現在要用兩個位元組表示,儲存空間放大了一倍,在現在的網路頻寬還非常有限的情況下,這樣會增大網路傳輸的流量,而且也沒有必要。
UTF-8採用一種變長技術,每個編碼區域有不同的字碼長度。不同的字元可以由1~6個位元組組成。
UTF-8有以下編碼規則:
  • 如果是1個位元組,最高位(第8位)為0,則表示這是1個ASCII字元(00~7F)。可見,所有ASCII編碼已經是UTF-8了。
  • 如果是1個位元組,以11開頭,則連續的1的個數暗示這個字元的位元組數,例如;110xxxxx代表它是雙位元組UTF-8字元的首位元組。
  • 如果是1個位元組,以10開始,表示它不是首位元組,則需要向前查詢才能得到當前字元的首位元組。


在I/O操作中存在的編碼

InputStreamReader類可以將I/O操作中讀取到的位元組流轉換為字元流,其部分原始碼如下:
package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.StreamDecoder;

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;

    /**
     * Creates an InputStreamReader that uses the default charset.
     *
     * @param  in   An InputStream
     */
    public InputStreamReader(InputStream in) {
	super(in);
        try {
	    sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
	    // The default encoding should always be available
	    throw new Error(e);
	}
    }

    /**
     * Creates an InputStreamReader that uses the named charset.
     *
     * @param  in
     *         An InputStream
     *
     * @param  charsetName
     *         The name of a supported
     *         {@link java.nio.charset.Charset </code>charset<code>}
     *
     * @exception  UnsupportedEncodingException
     *             If the named charset is not supported
     */
    public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
	super(in);
	if (charsetName == null)
	    throw new NullPointerException("charsetName");
	sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }

    /**
     * Creates an InputStreamReader that uses the given charset. </p>
     *
     * @param  in       An InputStream
     * @param  cs       A charset
     *
     * @since 1.4
     * @spec JSR-51
     */
    public InputStreamReader(InputStream in, Charset cs) {
        super(in);
	if (cs == null)
	    throw new NullPointerException("charset");
	sd = StreamDecoder.forInputStreamReader(in, this, cs);
    }

    /**
     * Creates an InputStreamReader that uses the given charset decoder.  </p>
     *
     * @param  in       An InputStream
     * @param  dec      A charset decoder
     *
     * @since 1.4
     * @spec JSR-51
     */
    public InputStreamReader(InputStream in, CharsetDecoder dec) {
        super(in);
	if (dec == null)
	    throw new NullPointerException("charset decoder");
	sd = StreamDecoder.forInputStreamReader(in, this, dec);
    }
}
InputStreamReader內部包含一個StreamDecoder例項引用,對具體位元組到字元的解碼實現,其實是由StreamDecoder來完成的,在StreamDecoder解碼過程中必須由使用者指定Charset編碼格式,若使用者未指定Charset,則將使用本地環境中的預設字符集,如在中文環境中將使用GBK編碼。寫的情況也類似,OutputStreamWriter委託StreamEncoder將字元編碼成位元組。
package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import sun.nio.cs.StreamEncoder;

public class OutputStreamWriter extends Writer {

    private final StreamEncoder se;

    /**
     * Creates an OutputStreamWriter that uses the named charset.
     *
     * @param  out
     *         An OutputStream
     *
     * @param  charsetName
     *         The name of a supported
     *         {@link java.nio.charset.Charset </code>charset<code>}
     *
     * @exception  UnsupportedEncodingException
     *             If the named encoding is not supported
     */
    public OutputStreamWriter(OutputStream out, String charsetName)
	throws UnsupportedEncodingException
    {
	super(out);
	if (charsetName == null)
	    throw new NullPointerException("charsetName");
	se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
    }

    /**
     * Creates an OutputStreamWriter that uses the default character encoding.
     *
     * @param  out  An OutputStream
     */
    public OutputStreamWriter(OutputStream out) {
	super(out);
	try {
	    se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
	} catch (UnsupportedEncodingException e) {
	    throw new Error(e);
        }
    }

    /**
     * Creates an OutputStreamWriter that uses the given charset. </p>
     *
     * @param  out
     *         An OutputStream
     *
     * @param  cs
     *         A charset
     *
     * @since 1.4
     * @spec JSR-51
     */
    public OutputStreamWriter(OutputStream out, Charset cs) {
	super(out);
	if (cs == null)
	    throw new NullPointerException("charset");
	se = StreamEncoder.forOutputStreamWriter(out, this, cs);
    }

    /**
     * Creates an OutputStreamWriter that uses the given charset encoder.  </p>
     *
     * @param  out
     *         An OutputStream
     *
     * @param  enc
     *         A charset encoder
     *
     * @since 1.4
     * @spec JSR-51
     */
    public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
	super(out);
	if (enc == null)
	    throw new NullPointerException("charset encoder");
	se = StreamEncoder.forOutputStreamWriter(out, this, enc);
    }
}

以下是使用InputStreamReader和OutputStreamWriter進行位元組流到字元流的一個簡單示例。

public static void main(String[] args) throws IOException {

		String file = "d:/stream.txt";
		String charset = "UTF-8";
		String string = "這是要儲存的中文字元";

		FileOutputStream fos = new FileOutputStream(file);
		OutputStreamWriter osw = new OutputStreamWriter(fos, charset);
		try {
			osw.write(string);

		} finally {
			osw.close();
		}

		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis, charset);
		StringBuffer sb = new StringBuffer();
		char[] buf = new char[64];
		int count = 0;
		try {
			while ((count = isr.read(buf)) != -1) {
				sb.append(buf, 0, count);
			}

		} finally {
			isr.close();
		}
		System.out.println(sb.toString());
	}

在記憶體操作中的編碼

String類提供了轉換到位元組的方法,也支援將位元組轉換為字串的建構函式。

public static void main(String[] args) throws UnsupportedEncodingException {
		String s="這是一段中文字串";
		byte[] bytes=s.getBytes("UTF-8");
		String string=new String(bytes,"UTF-8");
	}
Charset類提供encode()與decode(),分別對應char[]到byte[]的編碼和byte[]到char[]的解碼。
public static void main(String[] args) {
		Charset cs = Charset.forName("UTF-8");
		ByteBuffer byteBuffer = cs.encode("這是要編碼的字串");
		CharBuffer charBuffer = cs.decode(byteBuffer);
	}

ByteBuffer提供一種char和byte之間的軟轉換,它們之間轉換不需要編碼和解碼,只是把一個16bit的char拆分為2個8bit的byte表示,它們的實際值並沒有被修改,僅僅是資料的型別做了轉換。

public static void main(String[] args) {
		ByteBuffer heapByteBuffer = ByteBuffer.allocate(1024);
		ByteBuffer buffer = heapByteBuffer.putChar('中');
		System.out.print(Integer.toBinaryString(buffer.get(0)) + " ");
		System.out.print(Integer.toBinaryString(buffer.get(1)));
	}

列印結果:

1001110 101101

編碼問題(char-encoding-problem)典型示例:

public class EncodeTest {
	static String toHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder("");
		if (bytes == null || bytes.length == 0) {
			return null;
		}
		for (int i = 0; i < bytes.length; i++) {
			int v = bytes[i] & 0xFF;

			String hv = Integer.toHexString(v);
			sb.append(hv + " ");
		}
		return sb.toString();
	}

	static String toHexString(char[] chars) {
		StringBuilder sb = new StringBuilder("");
		if (chars == null || chars.length == 0) {
			return null;
		}
		for (int i = 0; i < chars.length; i++) {
			String hv = Integer.toHexString((int) chars[i]);
			sb.append(hv + " ");
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		String string = "I am 李";
		// Unicode十進位制數值為:    73       32       97       109      32       26446
		// Unicode十六進位制字串:  49       20       61       6d       20       674e
		// Unicode二進字串:      01001001 00100000 01100001 01101101 00100000 0110011101001110
		try {
			byte[] iso8859 = string.getBytes("ISO-8859-1");
			byte[] gb2312 = string.getBytes("GB2312");
			byte[] gbk = string.getBytes("GBK");
			byte[] utf16 = string.getBytes("UTF-16");
			byte[] utf8 = string.getBytes("UTF-8");

			System.out.println(toHexString(string.toCharArray()));
			// 輸出結果:49 20 61 6d 20 674e
			
			/**
			 * ISO-8859-1編碼會將不支援的字元編碼為3f,即"?"字元。
			 */
			System.out.println(toHexString(iso8859));
			// 輸出結果:49 20 61 6d 20 3f
			
			/**
			 * GB2312字符集有一個從char到byte的碼錶,不同的字元編碼就是從這個碼錶找到與每個字元對應的位元組,然後拼裝成byte陣列。
			 */
			System.out.println(toHexString(gb2312));
			// 輸出結果:49 20 61 6d 20 c0 ee
			
			/**
			 * GBK編碼相容GB2312編碼,且GBK包含的漢字字元更多。
			 */
			System.out.println(toHexString(gbk));
			// 輸出結果:49 20 61 6d 20 c0 ee
			
			/**
			 * UTF-16僅將字元的高位與低位進行拆分變成兩個位元組,特點是編碼效率非常高,規則很簡單
			 * 前面用兩個位元組來儲存BYTE_ORDER_MARK值,用來區分是高位位元組在前,或者低位位元組在前。
			 */
			System.out.println(toHexString(utf16));
			// 輸出結果:fe ff 0 49 0 20 0 61 0 6d 0 20 67 4e 
			
			/**
			 * UTF-8編碼也不用查表,效率很高,變長儲存節省空間。
			 */
			System.out.println(toHexString(utf8));
			// 輸出結果:49 20 61 6d 20 e6 9d 8e 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

在Java Web中涉及的編解碼

URL的編解碼

使用者提交一個URL,在這個URL中可能存在中文,因此需要編碼。

Apache Tomcat對URL的URI部分進行解碼的字符集是在Connector的<Connector URIEncoding="UTF-8"/>中定義的,如果沒有定義,那麼將以預設編碼ISO-8859-1解析。所以有中文URL時最好把URIEncoding設定成UTF-8編碼。

CATALINA_HOME\conf\server.xml中修改Connector 配置如下:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8483"  URIEncoding="UTF-8"/>
URL中以Get方式請求的QueryString的解碼是在request.getParameter()方法第一次被呼叫時進行的,解碼字符集要麼是Header中ContentType定義的Charset,要麼是預設的ISO-8859-1,要使用ContentType中定義的編碼,就要將Connector的<Connector  URIEncoding="UTF-8" useBodyEncodingForURI="true"/>中的useBodyEncodingForURI設定為true,對QueryString使用BodyEncoding解碼。
CATALINA_HOME\conf\server.xml中修改Connector 配置如下:
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8483"  URIEncoding="UTF-8" useBodyEncodingForURI="true"/>

HTTP Header的編解碼

當客戶端發起一個HTTP請求時,在Header中可能會傳遞其他引數,如Cookie、redirectPath等,對於這些引數Tomcat預設使用ISO-8859-1解碼,並且不能設定成其他的解碼格式。因此,如果你設定的Header中含有非ASCII字元,解碼中肯定會有亂碼。一個簡單的解決辦法:可以先將這些字元用org.apache.catalina.util.URLEncoder編碼,再新增到Header中,使用這些項時再按照相應的字符集解碼即可。

POST表單的編解碼

POST表單提交的引數的解碼也是在request.getParameter()方法第一次被呼叫時發生的,POST表單的引數傳遞方法與QueryString不同,它是通過HTTP的BODY傳遞到服務端的。當我們在頁面上單擊提交按鈕時瀏覽器首先將根據ContentType的Charset編碼格式對在表單中填入的引數進行編碼,然後提交到伺服器端,在伺服器端同樣也是用ContentType中的字符集進行解碼的。所以通過POST表單提交的引數一般不會出現問題,而且這個字符集編碼是我們自己設定的,可以通過request.setCharacterEncoding(charset)來設定。
注意:要在第一次呼叫request.getParameter()方法之前就設定request.setCharacterEncoding(charset),否則POST表單提交上來的資料可能出現亂碼。

HTTP BODY的編解碼

當用戶請求的資源已經成功獲取後,這些內容將通過Response返回給客戶端瀏覽器,這個過程要先經過編碼,再到瀏覽器進行解碼。編解碼字符集可以通過response.setCharacterEncoding來設定,它將會覆蓋request.getCharacterencoding的值,並且通過Header的Content-Type返回客戶端,瀏覽器接收到返回的Socket流時將通過Content-Type的charset來解碼。如果返回的HTTP Header中Content-Type沒有設定charset,那麼瀏覽器將根據HTML的<meta HTTP-equiv="Content-Type" content="text/html; charset=GBK" />中的charset來解碼。如果也沒有定義,那麼瀏覽器將使用預設的編碼來解碼。
訪問資料庫都是通過客戶端JDBC驅動來完成的,用JDBC來存取資料時要和資料的內建編碼保持一致,可以通過設定JDBC URL來指定,如MYSQL:url=“jdbc:mysql://localhost:3306/DB?useUnicode=true&characterEncoding=GBK”。

在JS中的編碼問題

外部引入JS檔案

在一個單獨的JS檔案中包含字串輸入 的情況,如:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script src="script.js" charset="gbk"></script>
</head>
</html>

如果引入的script.js指令碼中有如下程式碼:

document.write("這是一段中文");

這時如果script沒有設定cahrset,瀏覽器就會以當前這個頁面的預設字符集解析這個JS檔案。當script.js檔案與當前頁面的編碼格式不一致時,就會出現亂碼。

JS的URL編碼

在JS中處理URL編碼的函式有三個:escape()、encodeURI()和encodeURIComponent()。
escape()
這個函式是將ASCII字母、數字、標點符號(* + - . / @ _)之外的其他字元轉化成Unicode編碼值,並且在編碼值前加上“%u”,通過unescape()函式解碼,如圖所示。 注意:escape()和unescape()已經從ECMAScript V3 標準中刪除了,URL的編碼可以用encodeURI和encodeURIComponent來代替。
encodeURI()
與escap()相比,encodeURI()是真正的JS用來對URL編碼的函式,它可以將整個URL中的字元(一些特殊字元除外,如:! # $ & ' ( ) * + , -  . / : ; = ? @ _ ~ 0-9 a-z A-Z)進行UTF-8編碼,在每個碼值前加上“%”,解碼通過decodeURI()函式,如圖所示。
encodeURIComponent()
encodeURIComponent()這個函式比encodeURI()編碼還要徹底,它除了對 ! ' ( ) * - . _ ~ 0-9 a-z A-Z這幾個字元不編碼,對其他所有字元都編碼。這個函式通常用於將一個URL當作一個引數放在另一個URL中,解碼通過decodeURIComponent()函式,如圖所示。

Java與JS編解碼問題

在Java端處理URL編解碼有兩個類,分別是 java.net.URLEncoder和java.net.URLDecoder。這兩個類可以將所有“%”加UTF-8碼值用UFT-8解碼,從而得到原始字元。Java端的URLEncoder和URLDecoder與前端JS對應的是encodeURIComponent和decodeURIComponent。
注意:可以用encodeURIComponent兩次編碼,如encodeURIComponent(encodeURIComponent(str)),這樣在Java端通過request.getParameter()用GBK解碼後取得的就是UTF-8編碼的字串,如果Java端需要使用這個字串,則再用UTF-8解碼一次;如果是將這個結果直接通過JS輸出到前端,那麼這個UTF-8字串可以直接在前端正常顯示。

其他需要編碼的地方

XML檔案可以通過設定頭來指定編碼格式:
<?xml version="1.0" encoding="UTF-8"?>
Velocity模板設定編碼的格式如下:
services.VelocityService.input.encoding=UTF-8
JSP設定編碼的格式如下:
<%@page contentType="text/html;charset=UTF-8"%>

相關推薦

JAVA字元編碼

參考書籍:《深入分析Java Web技術內幕(修訂版)》----許令波著 編碼問題一直在困擾著程式開發人員,這在Java中尤其突出,因為Java是跨平臺語言,字元在不同平臺之間進行傳輸時經常需要進行編碼切換。 為什麼要編碼? 眾所周知,計算機其實是很笨的,它只識別數字0和

Java之路字元編碼

計算機裡只有數字,計算機軟體裡的一切都是用數字來表示,螢幕上顯示的一個個字元也不例外。 最開始計算機是在美國使用,當時所用到的字元也就是現在鍵盤上的一些符號和少數幾個特殊的符號,每一個字元都用一個數字來表示,一個位元組所能表示的數字範圍內(0~255)足以容納所有的字元,實

JVMJava物件的記憶體結構

物件記憶體結構 Class檔案以位元組碼的形式儲存在方法區當中,用來描述一個類本身的記憶體結構。當使用Class檔案新建物件時,物件例項的記憶體結構又究竟是個什麼樣子呢?   如圖所示,為了表示物件的屬性、方法等資訊,HotSpot VM使用物件頭部的一個指標指向Class區域的方式來

Java IO4字元編碼

前言       字元編碼,這本不屬於IO的內容,但位元組流之後寫的應該是字元流,既然是字元流,那就涉及一個"字元編碼的"問題,考慮到字元編碼不僅僅是在IO這塊,Java中很多場景都涉及到這個概念,因此這邊文章就專門詳細寫一下字元編碼,具體的網上有很多,但

PHP介面字元編碼和資料格式由請求方定義

根據一個老專案寫介面,發現專案檔案編碼為gbk,而且資料庫也是gbk,由於程式碼量巨大,不可能更改專案程式碼以及資料庫的字元編碼。 請求介面的也有好多個: 老客戶一直用的gbk字元編碼的資料來請求的,原來寫的介面收到的資料格式為xml, 新客戶要求用utf-8格式,接收資料為json。 看了

Java工具類-轉換字元編碼

package common; /** *字串處理公用類 */ public class DealString { /** * 轉換字元編碼 由“iso-8859-1”西文轉換為簡體中文 */ public static String toGb(

Java工具類-設定字元編碼

package common; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; i

Java記憶體中的字元編碼

  Java記憶體中的字元編碼 Unicode字符集及utf-8 、utf-16、utf-32 等字元編碼方式 字符集:字元表示的數字集合,元素稱為碼點或碼位; 字元編碼:字元實際的儲存表示; 碼點:一個碼點對應 一個字元;   utf-8編碼:可變長編碼,一個字元編

Java——I/O(字元編碼、記憶體流、列印流、System、輸入流、序列化)

1.常見的編碼  GBK、GB2312:國標編碼,GBK包含簡體中文和繁體中文,而GB2312只包含簡體中文。 UNICODE編碼:java提供的16進位制編碼,可以描述世界上任意的文字資訊。由於使用16進位制編碼,編碼體積太大,造成網路傳輸的負擔。 ISO8859-1:國際通

Redis主從Replication的配置

概述 Redis的replication機制允許slave從master那裡通過網路傳輸拷貝到完整的資料備份。具有以下特點: 非同步複製。從2.8版本開始,slave能不時地從master那裡獲取到資料。允許單個master配置多個slaveslave允許其它slave連線

.NET(C#)字元編碼(Encoding)和位元組順序標記(BOM)

什麼是字元順序標記(BOM) 計算機內部資料儲存都是二進位制的,只有知道一段資料的二進位制儲存格式,這段資料才有意義。所謂的文字檔案其實就是用一種特定的字元編碼來將二進位制源資料轉換成文字。多數文字編輯器都可以編輯不同編碼的文字檔案,那麼文字編輯器是怎樣通過源二

MyBatis自定義TypeHandler處理列舉

TypeHandler簡介 在MyBatis中,StatementHandler負責對需要執行的SQL語句進行預編譯處理,主要完成以下兩項工作:1.呼叫引數處理器(ParameterHandler)來設定需要傳入SQL的引數;2.呼叫結果集處理器(ResultSetHand

廖雪峰老師Python學習(2)字元編碼

字元編碼 我們已經講過了,字串也是一種資料型別,但是,字串比較特殊的是還有一個編碼問題。 因為計算機只能處理數字,如果要處理文字,就必須先把文字轉換為數字才能處理。最早的計算機在設計時採用8個位元(bit)作為一個位元組(byte),所以,一個位元組能表示的最大的整數就是255(二進位制11

JS 和 Java 中URL特殊字元編碼方式

 JavaScript   1.  編碼 escape(String)     其中某些字元被替換成了十六進位制的轉義序列。    解碼 unescape(String)     該函式的工作原理是這樣的:通過找到形式為 %xx 和 %uxxxx 的字元序列(x

Python字元編碼詳解

相關文章 1. 字元編碼簡介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一種單位元組的編碼。計算機世界裡一開始只有英文,而單位元組可以表示256個不同的字元,可以表示所有的英文字元和許多的控制符號。不過

JVM垃圾收集器(一)

參考書籍:《深入理解Java虛擬機器——JVM高階特性與最佳實踐(第2版)》 Java語言出來之前,程式開發更多的是使用C或者C++語言,然而在C或者C++語言中存在一個很大的矛盾:建立物件時要不斷

Python筆記字元編碼unicode/utf-8

請尊重原創作品。轉載請保持文章完整性,並以超連結形式註明原始作者“tingsking18”和主站點地址,方便其他朋友提問和指正。 Unicode和Python的中文處理   在Python語言中,Uincode字串處理一直是一個容易讓人迷惑的問題。許多Python

RedisHash操作常用命令

HGET命令 命令語法:HGET key field命令用途:返回雜湊表鍵 key 中給定域 field 的值。時間複雜度:O(1) 127.0.0.1:6379> exists book (

Java-RPC2)NIO入門

Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API,可以替代標準的Java IO APIChannels and Buffers(通道和緩衝區):標準的IO基於位元組流和字元流進行操作的,而NIO是基於通道(Channel)和緩衝區(Bu

Java從入門到失業》第三章基礎語法及基本程式結構(四)基本資料型別(字元編碼和char型)

3.6.4字元編碼        咦?怎麼好像有東西亂入了?不是講基本資料型別麼?哈哈,因為還剩下最後一個char型了,因為char型會牽涉到Unicode編碼相關,因此我決定先科普一下字符集編碼。     &