Java 編譯楚堤、運(yùn)行過程中的字符編碼

前言

近日遇到一個(gè)神奇的問題疫蔓,在github上找了開源庫,使用如下兩種不同的運(yùn)行方式得到的運(yùn)行結(jié)果也不同身冬,但理論上運(yùn)行結(jié)果應(yīng)該是一致的才是衅胀。

  • 方式一: 將源碼編譯為jar包,使用java -jar xxx 的方式運(yùn)行得到的運(yùn)行結(jié)果是正常的酥筝。(源碼作者使用的方式)

  • 方式二: 將源代碼導(dǎo)入IDEA中滚躯,使用IDEA來運(yùn)行main()的方式得到的運(yùn)行結(jié)果是異常的。

    以上兩種運(yùn)行的方式從理論上沒有什么差別的,那么為何會(huì)得出不同的運(yùn)行結(jié)果呢掸掏?在經(jīng)過查閱資料和同事的討論以及一系列的驗(yàn)證后終于找出問題的根本原因----Java編譯茁影、運(yùn)行過程中的字符編碼導(dǎo)致的。

1丧凤、字符編碼與解碼

1.1募闲、基本概念

在了解字符編碼與解碼之前我們先需要知道字符集的概念。字符是用戶可以讀寫的最小單位愿待,計(jì)算機(jī)所能支持的字符組成的集合浩螺,就叫做字符集。字符集通常以二維表的形式存在呼盆。二維表的內(nèi)容和大小是由使用者的語言而定年扩。
顧名思義,編碼就是把一個(gè)字符編碼成二進(jìn)制碼存起來的方式访圃。相應(yīng)的,將編碼的字節(jié)還原成字符的操作就叫做解碼相嵌。編碼和解碼都是需要按照一定的規(guī)則腿时,把字符集中的字符編碼為特定的二進(jìn)制數(shù)的規(guī)則就是字符編碼。

1.2饭宾、為什么要編碼批糟?

由于人類的語言太多,因而表示這些語言的符號(hào)太多看铆,無法使用計(jì)算機(jī)中一個(gè)基本存儲(chǔ)單位--字節(jié) 來表示徽鼎,因而必須要經(jīng)過拆分或一些翻譯工作,才能讓計(jì)算機(jī)理解弹惦。計(jì)算機(jī)中一個(gè)字節(jié)所能表示的字符范圍是0-255個(gè)否淤。人類要表示的符號(hào)太多,無法使用一個(gè)字節(jié)來完全表示棠隐,這就需要使用編碼來解決這個(gè)問題石抡。

1.3、常見的編碼格式

1.3.1助泽、 ASCII碼

上世紀(jì)60年代啰扛,美國制定了一套字符編碼,對(duì)英語字符與二進(jìn)制之間的關(guān)系嗡贺,做了統(tǒng)一規(guī)定隐解。這被稱為ASCII碼。ASCII碼一共規(guī)定了128個(gè)字符的編碼诫睬,用一個(gè)字節(jié)的低7位表示煞茫,最高位統(tǒng)一規(guī)定為0。0-31是控制字符如換行、回車等溜嗜;32-126是打印字符宵膨,可以通過鍵盤輸入并且能夠顯示出來。

1.3.2炸宵、 ISO-8859-1

128個(gè)字符顯然是不夠用的辟躏,于是ISO組織在ASCII碼基礎(chǔ)上又制定了一系列標(biāo)準(zhǔn)用來擴(kuò)展ASCII碼,ISO-8859-1涵蓋了大多數(shù)西歐語言字符土全。ISO-8859-1仍然是單字節(jié)編碼捎琐,它總共能表示256個(gè)字符。

1.3.3裹匙、 GBK

全稱叫《漢字內(nèi)碼擴(kuò)展規(guī)范》瑞凑,是國家技術(shù)監(jiān)督局為windows95制定的新的漢字內(nèi)碼規(guī)范,它的出現(xiàn)是為了擴(kuò)展GB2312,加入更多的漢字概页。

1.3.4籽御、 Unicode

隨著計(jì)算機(jī)的發(fā)展,各國都推出各自的編碼標(biāo)準(zhǔn)惰匙,互不兼容技掏,非常不利于全球化發(fā)展。于是Unicode誕生了项鬼,它為每種語言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼哑梳,計(jì)算機(jī)只要支持這一個(gè)字符集,就能顯示所有的字符绘盟,再也不會(huì)有亂碼了鸠真。Unicode理論上最多能表示2的31次方個(gè)字符,完全可以涵蓋一切語言所用的符號(hào)龄毡。

對(duì)于 Unicode 有一些誤解吠卷,它僅僅只是一個(gè)字符集,規(guī)定了符合對(duì)應(yīng)的二進(jìn)制代碼稚虎,至于這個(gè)二進(jìn)制代碼如何存儲(chǔ)則沒有任何規(guī)定撤嫩,所以這也造成了一些問題。比如蠢终,漢字"嚴(yán)"的 Unicode 是十六進(jìn)制數(shù)4E25序攘,轉(zhuǎn)換成二進(jìn)制數(shù)足足有15位(100111000100101),也就是說寻拂,這個(gè)符號(hào)的表示至少需要2個(gè)字節(jié)程奠。表示其他更大的符號(hào),可能需要3個(gè)字節(jié)或者4個(gè)字節(jié)祭钉,甚至更多瞄沙。

因?yàn)橹辽傩枰?個(gè)字節(jié)來表示更大的符號(hào),這就導(dǎo)致了兩個(gè)問題:
1.如何區(qū)別該編碼是Unicode還是ASCII,計(jì)算機(jī)怎么知道該字符是2個(gè)字節(jié)還是3個(gè)字節(jié)甚至更多距境。
2.眾所周知申尼,英文字母只需要一個(gè)字節(jié)來進(jìn)行編碼,但是如果用2個(gè)字節(jié)3個(gè)字節(jié)甚至更多字節(jié)來表示這就會(huì)造成相應(yīng)倍數(shù)的存儲(chǔ)空間的增加垫桂,造成了存儲(chǔ)空間上的極大浪費(fèi)师幕。
所以最后也出現(xiàn)了Unicode的多種存儲(chǔ)方式,也就是說有許多種不同的二進(jìn)制格式來表示Unicode诬滩。
Unicode的實(shí)現(xiàn)方式也稱為Unicode轉(zhuǎn)換格式(Unicode Transformation Format,簡稱UTF)霹粥,目前主流的實(shí)現(xiàn)方式有UTF-8和UTF-16。以下就分別介紹UTF-8和UTF-16疼鸟。

1.3.5后控、 UTF-8

UTF-8是針對(duì)Unicode的一種可變長度字符編碼。它可以用來表示Unicode標(biāo)準(zhǔn)中的任何字符空镜,因而其編碼中的第一個(gè)字節(jié)仍與ASCII相容浩淘。UTF-8使用1~4字節(jié)為每個(gè)字符編碼,根據(jù)不同的字符而變化字節(jié)長度姑裂。
編碼規(guī)則如下:

Unicode 十六進(jìn)制碼點(diǎn)范圍 UTF-8二進(jìn)制
0000 0000 - 0000 007F 0xxxxxxx
0000 0080 - 0000 07FF 110xxxxx 10xxxxxx
0000 0800 - 0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000 - 0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

根據(jù)上表可得出如下結(jié)論:
1.如果一個(gè)字節(jié)馋袜,最高位(第八位)為0,表示這是一個(gè)ASCII字符舶斧。可見察皇,所有的ASCII編碼已經(jīng)是UTF-8編碼茴厉。
2.如果一個(gè)字節(jié)以11開頭,連續(xù)的1的個(gè)數(shù)暗示這個(gè)字符的字節(jié)數(shù)什荣,例如:110xxxxx代表它是雙字節(jié)UTF-8字符的首字節(jié)矾缓。
3.如果一個(gè)字節(jié),是以10開始稻爬,表示它不是首字節(jié)嗜闻,需要向前查找才能得到當(dāng)前字符的首字節(jié)。
例子:

  • "漢"的 Unicode 碼點(diǎn)是 0x6c49(110 1100 0100 1001)桅锄,通過上面的對(duì)照表可以發(fā)現(xiàn)琉雳,0x0000 6c49 位于第三行的范圍,那么得出其格式為 1110xxxx 10xxxxxx 10xxxxxx友瘤。接著翠肘,從“漢”的二進(jìn)制數(shù)最后一位開始,從后向前依次填充對(duì)應(yīng)格式中的 x辫秧,多出的 x 用 0 補(bǔ)上束倍。這樣,就得到了“漢”的 UTF-8 編碼為 11100110 10110001 10001001。由此可以看出”漢“使用UTF-8編碼后是使用三個(gè)字節(jié)表示绪妹。
  • "A" 的 Unicode 碼點(diǎn)是 0x0041 ( 0100 0001)甥桂,通過上面的對(duì)照表可以發(fā)現(xiàn),0x0041位于第一行的范圍邮旷,那么得出其格式為0xxxxxx黄选。故”A"的UTF-8編碼為01000001±纫疲可以看出“A"使用UTF-8編碼后是使用單字節(jié)表示糕簿。
1.3.4.2、 UTF-16

UTF-16是Unicode字符編碼表的一種實(shí)現(xiàn)方式狡孔。即把Unicode字符集的抽象碼位映射為16位長的整數(shù)(即碼元懂诗,長度為2byte)的序列引用,用于數(shù)據(jù)存儲(chǔ)或傳遞苗膝。Unicode字符碼位殃恒,需要1個(gè)或者2個(gè)16位長的碼元表示,因此這是一個(gè)變長表示辱揭。

在了解 UTF-16 編碼方式之前离唐,先了解一下另外一個(gè)概念——"平面"。

在上面的介紹中问窃,提到了 Unicode 是一本很厚的字典亥鬓,她將全世界所有的字符定義在一個(gè)集合里。這么多的字符不是一次性定義的域庇,而是分區(qū)定義嵌戈。每個(gè)區(qū)可以存放 65536 個(gè)(2^16) 字符,稱為一個(gè)平面(plane)听皿。目前熟呛,一共有17個(gè)(2^5)平面,也就是說尉姨,整個(gè) Unicode 字符集的大小現(xiàn)在是 2^21庵朝。

最前面的 65536 個(gè)字符位,稱為基本平面(簡稱 BMP )又厉,它的碼點(diǎn)范圍是從 0 到 2^16-1九府,寫成 16 進(jìn)制就是從 U+0000 到 U+FFFF。所有最常見的字符都放在這個(gè)平面馋没,這是 Unicode 最先定義和公布的一個(gè)平面昔逗。剩下的字符都放在輔助平面(簡稱 SMP ),碼點(diǎn)范圍從 U+010000 到 U+10FFFF篷朵。

基本了解了平面的概念后勾怒,再說回到 UTF-16婆排。UTF-16 編碼介于 UTF-32 與 UTF-8 之間,同時(shí)結(jié)合了定長和變長兩種編碼方法的特點(diǎn)笔链。它的編碼規(guī)則很簡單:基本平面的字符占用 2 個(gè)字節(jié)段只,輔助平面的字符占用 4 個(gè)字節(jié)。也就是說鉴扫,UTF-16 的編碼長度要么是 2 個(gè)字節(jié)(U+0000 到 U+FFFF)赞枕,要么是 4 個(gè)字節(jié)(U+010000 到 U+10FFFF)。那么問題來了坪创,當(dāng)我們遇到兩個(gè)字節(jié)時(shí)炕婶,到底是把這兩個(gè)字節(jié)當(dāng)作一個(gè)字符還是與后面的兩個(gè)字節(jié)一起當(dāng)作一個(gè)字符呢?

這里有一個(gè)很巧妙的地方莱预,在基本平面內(nèi)柠掂,從 U+D800 到 U+DFFF 是一個(gè)空段,即這些碼點(diǎn)不對(duì)應(yīng)任何字符依沮。因此涯贞,這個(gè)空段可以用來映射輔助平面的字符。

輔助平面的字符位共有 2^20 個(gè)危喉,因此表示這些字符至少需要 20 個(gè)二進(jìn)制位宋渔。UTF-16 將這 20 個(gè)二進(jìn)制位分成兩半,前 10 位映射在 U+D800 到 U+DBFF辜限,稱為高位(H)皇拣,后 10 位映射在 U+DC00 到 U+DFFF,稱為低位(L)薄嫡。這意味著审磁,一個(gè)輔助平面的字符,被拆成兩個(gè)基本平面的字符表示岂座。

因此,當(dāng)我們遇到兩個(gè)字節(jié)杭措,發(fā)現(xiàn)它的碼點(diǎn)在 U+D800 到 U+DBFF 之間费什,就可以斷定,緊跟在后面的兩個(gè)字節(jié)的碼點(diǎn)手素,應(yīng)該在 U+DC00 到 U+DFFF 之間鸳址,這四個(gè)字節(jié)必須放在一起解讀。

UTF-16編碼以16位無符號(hào)整數(shù)為單位泉懦。我們把Unicode編碼記作U稿黍。編碼規(guī)則如下:

平面 Unicode 十六進(jìn)制碼點(diǎn)范圍 UTF-16 二進(jìn)制
基本平面 0000 0000 - 0000 FFFF xxxx xxxx xxxx xxxx
增補(bǔ)平面 0001 0000 - 0010 FFFF 1101 10yy yyyy yyyy 1101 11xx xxxx xxxx
  • 如果U<0x10000,U的UTF-16編碼就是U對(duì)應(yīng)的16位無符號(hào)整數(shù)崩哩。
  • 如果U≥0x10000巡球,我們先計(jì)算U'=U-0x10000言沐,然后將U'寫成二進(jìn)制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16編碼(二進(jìn)制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx酣栈。

對(duì)于輔助平面的字符险胰,由于超過了一個(gè)16位可以表示的長度,所以需要兩個(gè)16位來表示矿筝。處于前面的16位被稱為前導(dǎo)起便,而后面的被稱為后綴。所以UTF-16要么是2字節(jié)窖维,要么是4字節(jié)榆综。
例子:

  • ?? (不是吉)的Unicode碼點(diǎn)為 0x20BB7,該碼點(diǎn)顯然超出了基本平面的范圍(0x0000 - 0xFFFF)铸史,因此需要使用四個(gè)字節(jié)表示鼻疮。首先用 0x20BB7 - 0x10000 計(jì)算出超出的部分,然后將其用 20 個(gè)二進(jìn)制位表示(不足前面補(bǔ) 0 )沛贪,結(jié)果為0001000010 1110110111陋守。接著,將前 10 位映射到 U+D800 到 U+DBFF 之間利赋,后 10 位映射到 U+DC00 到 U+DFFF 即可水评。這樣得到的結(jié)果就是1101 1000 0100 0010 1101 1111 1011 0111。由此可以看出”吉“使用UTF-16編碼后是使用四個(gè)字節(jié)媚送。
  • 的Unicode碼點(diǎn)為0x4EC0中燥,該碼點(diǎn)在基本平面(0x0000 - 0xFFFF),因此僅需要兩個(gè)字節(jié)表示。即為0100 1110 1100 0000塘偎。

2疗涉、出現(xiàn)亂碼的原因

出現(xiàn)亂碼問題唯一的原因都是在char到byte或byte到char轉(zhuǎn)換中編碼和解碼的字符集不一致導(dǎo)致的,由于往往一次操作涉及到多次編解碼吟秩,所以出現(xiàn)亂碼時(shí)很難查找到底是哪個(gè)環(huán)節(jié)出現(xiàn)了問題咱扣。下面是幾種常見的現(xiàn)象:

  • 現(xiàn)象一: 解碼時(shí)用的字符集與編碼字符集不一致導(dǎo)致亂碼。
編解碼字符集不一致.png

如上圖所示:字符串"淘涵防!我喜歡闹伪!"編碼是采用GBK,但解碼時(shí)采用ISO-8859-I,這樣就會(huì)導(dǎo)致亂碼壮池。

  • 現(xiàn)象二: 字符在編碼時(shí)采用錯(cuò)誤的字符集編碼導(dǎo)致亂碼偏瓤。(如中文采用ISO-8859-I編碼方式)
    使用錯(cuò)誤的編碼方式.png

上述分析的兩個(gè)現(xiàn)象都是一次編解碼后出現(xiàn)亂碼,實(shí)際中字符傳輸會(huì)經(jīng)過多次編解碼椰憋,這樣出現(xiàn)亂碼就比較難分析厅克。如下圖所示:
多次編解碼.png

這種情況比較復(fù)雜,中文經(jīng)過多次編碼橙依,但其中有一次編碼或解碼不對(duì)证舟,就會(huì)出現(xiàn)亂碼硕旗。

3、java編譯褪储、運(yùn)行過程中的字符編碼

java在編譯和運(yùn)行的整個(gè)過程中編碼轉(zhuǎn)化大概如下圖:

java編譯卵渴、運(yùn)行過程中編碼格式.png

可以看到Java運(yùn)行時(shí)主要的兩個(gè)編碼就是UTF-8和UTF-16,而編譯的開始,就是將各種不同編碼的源代碼文件轉(zhuǎn)換成UTF-8鲤竹。
這里其實(shí)并不是UTF-8浪读,是一種modified UTF-8,這里就姑且認(rèn)為是UTF-8辛藻。

從上圖可以理解不管采用那種格式的源文件碘橘,只要正確告訴編譯器源文件的編碼格式,編譯器就會(huì)得到正確的結(jié)果吱肌。同時(shí)只要告訴JVM正確的輸出流需要的編碼格式痘拆,JVM就可以返回正確編碼格式的輸出流。

那么要想不產(chǎn)生亂碼就需要注意如下兩個(gè)環(huán)節(jié):

  1. 告訴編譯器你java源文件的編碼格式氮墨。
  2. 告訴jvm你顯示或者構(gòu)造字符串輸出流時(shí)的希望的編碼纺蛆。

3.1、編譯時(shí)的編碼轉(zhuǎn)換

眾所周知规揪,java源文件可以是任意的源碼桥氏,但是在編譯的時(shí)候,javac編譯器默認(rèn)會(huì)使用操作系統(tǒng)平臺(tái)的編碼進(jìn)行解析字符猛铅。在簡體中文的Windows上字支,平臺(tái)默認(rèn)編碼會(huì)是GBK,那么javac就會(huì)默認(rèn)假定輸入的Java源文件是以GBK編碼的奸忽。
要想正確編譯堕伪,需要使用 -encoding指定輸入的java源文件的編碼。
-encoding encoding Set the source file encoding name, such as EUC-JP and UTF-8. If -encoding is not specified, the platform default converter is used.
導(dǎo)致亂碼的不是Java源碼編譯器的“編碼”(寫出UTF-8格式到class文件中)的過程栗菜,而是“解碼”(讀入Java源碼內(nèi)容)的過程欠雌。

3.2、運(yùn)行時(shí)的編碼轉(zhuǎn)換

JVM中運(yùn)行時(shí)數(shù)據(jù)都是使用UTF-16進(jìn)行編碼的疙筹。為什么JVM使用的是UTF-16,而不適用兼容性更好的UTF-8呢桨昙?這是因?yàn)闅v史原因?qū)е翵VM運(yùn)行時(shí)的數(shù)據(jù)使用UTF-16的編碼。

由于成本問題不能放棄UTF-16腌歉,但是UTF-8的兼容性和流行程度,又使得JVM必須做點(diǎn)什么來使得其內(nèi)部數(shù)據(jù)不會(huì)被編碼方式影響齐苛,于是就有了這個(gè)modified UTF-8翘盖。

modified UTF-8是對(duì)UTF-16的再編碼,所以JVM無需解碼UTF-16的數(shù)據(jù)凹蜂,modified UTF-8代理碼元會(huì)處理這個(gè)映射關(guān)系馍驯。

可以在啟動(dòng)JVM時(shí)使用-Dfile.encoding=xxx來設(shè)置阁危。這個(gè)屬性決定了JVM輸出的字節(jié)流編碼格式。

3.3汰瘫、 Java的 file.encoding和sun.jun.encoding的屬性

Java的file.encoding屬性的設(shè)置Jvm運(yùn)行過程中默認(rèn)的字符編碼狂打,比如:new String(bytes)、String.getBytes()混弥、IO操作過程中等所用的默認(rèn)編碼格式都是file.encoding屬性的所決定趴乡。

Java的sun.jun.encoding屬性的主要設(shè)置下面三個(gè)地方的編碼:

  • 命令行參數(shù)
  • 主類名稱
  • 環(huán)境變量

4、開發(fā)中關(guān)于編碼的建議

在我們了解常用的編碼格式以及Java編譯蝗拿、運(yùn)行過程中的默認(rèn)編碼后晾捏,下面是關(guān)于實(shí)際開發(fā)中關(guān)于編碼的一些建議:

  1. 項(xiàng)目源文件編碼應(yīng)統(tǒng)一為UTF-8,從兼容性哀托、存儲(chǔ)效率惦辛、存儲(chǔ)容量等因素考慮UTF-8是最合適。(據(jù)情形而定仓手,對(duì)于含有大量中文或者其他二字節(jié)長的字符流來說胖齐,UTF-16可以節(jié)省大量的存儲(chǔ)空間)。
  2. 項(xiàng)目源文件的編碼應(yīng)統(tǒng)一嗽冒,即A.java和B.java的編碼格式應(yīng)統(tǒng)一呀伙。若不一致很容易造成亂碼。
  3. char與byte彼此轉(zhuǎn)換中應(yīng)指定編碼格式辛慰,不應(yīng)該使用默認(rèn)的編碼格式区匠。如:new String(bytes,"UTF-8")、String.getBytes("UTF-8")帅腌、IO操作中涉及到字符編碼等驰弄。
    上述三個(gè)建議,我們最容易忽略的是最后一個(gè)速客,最后一個(gè)也是我們就容易出現(xiàn)的一個(gè)戚篙。

5、總結(jié)

本文最開始描述了工作中遇到的一個(gè)神奇的問題溺职,使得我想去探究Java編譯岔擂、運(yùn)行過程中的編碼格式。正文中首先介紹了字符編碼與解碼的基本概念浪耘,接著介紹了常用的幾種編碼格式乱灵。然后分析了平常出現(xiàn)亂碼問題的原因。最后是本文的核心介紹了Java在編譯七冲、運(yùn)行過程中編碼格式以及如何保證不出現(xiàn)亂碼痛倚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市澜躺,隨后出現(xiàn)的幾起案子蝉稳,更是在濱河造成了極大的恐慌抒蚜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耘戚,死亡現(xiàn)場離奇詭異嗡髓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)收津,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門饿这,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朋截,你說我怎么就攤上這事蛹稍。” “怎么了部服?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵唆姐,是天一觀的道長。 經(jīng)常有香客問我廓八,道長奉芦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任剧蹂,我火速辦了婚禮声功,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宠叼。我一直安慰自己先巴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布冒冬。 她就那樣靜靜地躺著伸蚯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪简烤。 梳的紋絲不亂的頭發(fā)上剂邮,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音横侦,去河邊找鬼挥萌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛枉侧,可吹牛的內(nèi)容都是我干的引瀑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼榨馁,長吁一口氣:“原來是場噩夢啊……” “哼伤疙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤徒像,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蛙讥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锯蛀,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年次慢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旁涤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡迫像,死狀恐怖劈愚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闻妓,我是刑警寧澤菌羽,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站由缆,受9級(jí)特大地震影響注祖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜均唉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一是晨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舔箭,春花似錦罩缴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至怒医,卻和暖如春炉抒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稚叹。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工焰薄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扒袖。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓塞茅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親季率。 傳聞我的和親對(duì)象是個(gè)殘疾皇子野瘦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354