JAVA基礎(chǔ)知識(shí)之IO體系

Java 的 I/O 類庫(kù)的基本架構(gòu)

I/O 問(wèn)題是任何編程語(yǔ)言都無(wú)法回避的問(wèn)題,Java中使用IO(輸入輸出)來(lái)讀取和寫(xiě)入,讀寫(xiě)設(shè)備上的數(shù)據(jù)、硬盤(pán)文件底哗、內(nèi)存、鍵盤(pán)......锚沸,根據(jù)數(shù)據(jù)的走向可分為輸入流和輸出流跋选,這個(gè)走向是以內(nèi)存為基準(zhǔn)的,即往內(nèi)存中讀數(shù)據(jù)是輸入流哗蜈,從內(nèi)存中往外寫(xiě)是輸出流前标。正因如此坠韩,所以 Java 在 I/O 上也一直在做持續(xù)的優(yōu)化,如從 1.4 開(kāi)始引入了 NIO炼列,提升了 I/O 的性能只搁。

本文主要講IO體系與邏輯關(guān)系,不去細(xì)講如何使用類中的API與方法俭尖。文末有FileUtils和FileIOUtils可以將您所想要的所有有關(guān)流操作的相關(guān)代碼涵蓋氢惋,可進(jìn)行仔細(xì)觀看。

代碼傳送門(mén)
FileUtils
FileIOUtils

20190111132530.jpg

Java 的 I/O 操作類在包 java.io 下稽犁,大概有將近 80 個(gè)類焰望,從上圖可以看到,整個(gè)Java IO體系都是基于字符流(InputStream/OutputStream) 和 字節(jié)流(Reader/Writer)作為基類已亥,根據(jù)不同的數(shù)據(jù)載體或功能派生出來(lái)的熊赖。這些類大概可以分成四組,分別是:

  • 基于字節(jié)操作的 I/O 接口:InputStream 和 OutputStream

  • 基于字符操作的 I/O 接口:Writer 和 Reader

  • 基于磁盤(pán)操作的 I/O 接口:File

  • 基于網(wǎng)絡(luò)操作的 I/O 接口:Socket(不在IO分組中)

前兩組主要是根據(jù)傳輸數(shù)據(jù)的數(shù)據(jù)格式虑椎,后兩組主要是根據(jù)傳輸數(shù)據(jù)的方式震鹉。

字節(jié)流和字符流的區(qū)別(解惑)

  • 1.字節(jié)流讀取的時(shí)候,讀到一個(gè)字節(jié)就返回一個(gè)字節(jié)绣檬; 字符流使用了字節(jié)流讀到一個(gè)或多個(gè)字節(jié)(中文對(duì)應(yīng)的字節(jié)數(shù)是兩個(gè)足陨,在UTF-8碼表中是3個(gè)字節(jié))時(shí)嫂粟。先去查指定的編碼表娇未,將查到的字符返回。

  • 2.字節(jié)流可以處理所有類型數(shù)據(jù)星虹,如:圖片零抬,MP3,AVI視頻文件宽涌,而字符流只能處理字符數(shù)據(jù)平夜。只要是處理純文本數(shù)據(jù),就要優(yōu)先考慮使用字符流卸亮,除此之外都用字節(jié)流忽妒。

轉(zhuǎn)換流

  • InputStreamReader 是字節(jié)流通向字符流的橋梁

  • OutputStreamWriter 是字符流通向字節(jié)流的橋梁

  • 轉(zhuǎn)換流可以將字節(jié)轉(zhuǎn)成字符,原因在于兼贸,將獲取到的字節(jié)通過(guò)查編碼表獲取到指定對(duì)應(yīng)字符段直。 轉(zhuǎn)換流的最強(qiáng)功能就是基于 字節(jié)流 + 編碼表 。沒(méi)有轉(zhuǎn)換溶诞,沒(méi)有字符流鸯檬。

打印流

  • PrintWriter

  • PrintStream

    注打印流: A:只操作目的地,不操作數(shù)據(jù)源 B:可以操作任意類型的數(shù)據(jù) C:如果啟用了自動(dòng)刷新,在調(diào)用println(),printf(),format()方法的時(shí)候螺垢,能夠換行并刷新 D:可以直接操作文件

序列化流

  • ObjectOutputStream序列化流

  • ObjectInputStream反序列化流 序列化:把對(duì)象作為一個(gè)整體按照流一樣的方式傳輸或者存儲(chǔ)喧务。 反序列化:把網(wǎng)絡(luò)中的流數(shù)據(jù)或者文件中的流數(shù)據(jù)還原成對(duì)象

    主要方法有:

  • Object readObject();該方法拋出異常:ClassNotFountException赖歌。

  • void writeObject(Object):被寫(xiě)入的對(duì)象必須實(shí)現(xiàn)一個(gè)接口:Serializable,否則就會(huì)拋出:NotSerializableException

  • 如果實(shí)現(xiàn)了該接口功茴,想解決黃線問(wèn)題就生成一個(gè)隨機(jī)的serialVersionUID號(hào)碼

分析基于這兩個(gè)因素來(lái)展開(kāi)

基于字節(jié)的 I/O 操作接口

基于字節(jié)的 I/O 操作接口輸入和輸出分別是:InputStream 和 OutputStream庐冯,InputStream 輸入流的類繼承層次如下圖所示:

image

輸入流根據(jù)數(shù)據(jù)類型和操作方式又被劃分成若干個(gè)子類,每個(gè)子類分別處理不同操作類型坎穿,OutputStream 輸出流的類層次結(jié)構(gòu)也是類似肄扎,如下圖所示:

image

這里就不詳細(xì)解釋每個(gè)子類如何使用了,如果不清楚的話可以參考一下 JDK 的 API 說(shuō)明文檔赁酝,這里只想說(shuō)明兩點(diǎn)犯祠,一個(gè)是操作數(shù)據(jù)的方式是可以組合使用的,如這樣組合使用

還有一點(diǎn)是流最終寫(xiě)到什么地方必須要指定酌呆,要么是寫(xiě)到磁盤(pán)要么是寫(xiě)到網(wǎng)絡(luò)中衡载,其實(shí)從上面的類圖中我們發(fā)現(xiàn),寫(xiě)網(wǎng)絡(luò)實(shí)際上也是寫(xiě)文件隙袁,只不過(guò)寫(xiě)網(wǎng)絡(luò)還有一步需要處理就是底層操作系統(tǒng)再將數(shù)據(jù)傳送到其它地方而不是本地磁盤(pán)痰娱。關(guān)于網(wǎng)絡(luò) I/O 和磁盤(pán) I/O 我們將在后面詳細(xì)介紹。

基于字符的 I/O 操作接口

不管是磁盤(pán)還是網(wǎng)絡(luò)傳輸菩收,最小的存儲(chǔ)單元都是字節(jié)梨睁,而不是字符,所以 I/O 操作的都是字節(jié)而不是字符娜饵,但是為啥有操作字符的 I/O 接口呢坡贺?這是因?yàn)槲覀兊某绦蛑型ǔ2僮鞯臄?shù)據(jù)都是以字符形式,為了操作方便當(dāng)然要提供一個(gè)直接寫(xiě)字符的 I/O 接口箱舞,如此而已遍坟。我們知道字符到字節(jié)必須要經(jīng)過(guò)編碼轉(zhuǎn)換,而這個(gè)編碼又非常耗時(shí)晴股,而且還會(huì)經(jīng)常出現(xiàn)亂碼問(wèn)題愿伴,所以 I/O 的編碼問(wèn)題經(jīng)常是讓人頭疼的問(wèn)題。

下圖是寫(xiě)字符的 I/O 操作接口涉及到的類电湘,Writer 類提供了一個(gè)抽象方法 write(char cbuf[], int off, int len) 由子類去實(shí)現(xiàn)隔节。

image

讀字符的操作接口也有類似的類結(jié)構(gòu),如下圖所示:

image

讀字符的操作接口中也是 int read(char cbuf[], int off, int len)寂呛,返回讀到的 n 個(gè)字節(jié)數(shù)怎诫,不管是 Writer 還是 Reader 類它們都只定義了讀取或?qū)懭氲臄?shù)據(jù)字符的方式,也就是怎么寫(xiě)或讀昧谊,但是并沒(méi)有規(guī)定數(shù)據(jù)要寫(xiě)到哪去刽虹,寫(xiě)到哪去就是我們后面要討論的基于磁盤(pán)和網(wǎng)絡(luò)的工作機(jī)制。

字節(jié)與字符的轉(zhuǎn)化接口

另外數(shù)據(jù)持久化或網(wǎng)絡(luò)傳輸都是以字節(jié)進(jìn)行的呢诬,所以必須要有字符到字節(jié)或字節(jié)到字符的轉(zhuǎn)化涌哲。字符到字節(jié)需要轉(zhuǎn)化胖缤,其中讀的轉(zhuǎn)化過(guò)程如下圖所示:

image

InputStreamReader 類是字節(jié)到字符的轉(zhuǎn)化橋梁,InputStream 到 Reader 的過(guò)程要指定編碼字符集阀圾,否則將采用操作系統(tǒng)默認(rèn)字符集哪廓,很可能會(huì)出現(xiàn)亂碼問(wèn)題。StreamDecoder 正是完成字節(jié)到字符的解碼的實(shí)現(xiàn)類初烘。也就是當(dāng)你用如下方式讀取一個(gè)文件時(shí):

清單 1.讀取文件
try { 
           StringBuffer str = new StringBuffer(); 
           char[] buf = new char[1024]; 
           FileReader f = new FileReader("file"); 
           while(f.read(buf)>0){ 
               str.append(buf); 
           } 
           str.toString(); 
} catch (IOException e) {}

FileReader 類就是按照上面的工作方式讀取文件的涡真,F(xiàn)ileReader 是繼承了 InputStreamReader 類,實(shí)際上是讀取文件流肾筐,然后通過(guò) StreamDecoder 解碼成 char哆料,只不過(guò)這里的解碼字符集是默認(rèn)字符集。

寫(xiě)入也是類似的過(guò)程如下圖所示:

image

通過(guò) OutputStreamWriter 類完成吗铐,字符到字節(jié)的編碼過(guò)程东亦,由 StreamEncoder 完成編碼過(guò)程。

同步和異步唬渗、阻塞和非阻塞

同步和異步是針對(duì)IO來(lái)說(shuō)的典阵。所謂同步就是一個(gè)任務(wù)的完成需要依賴另外一個(gè)任務(wù)時(shí),只有等待被依賴的任務(wù)完成后镊逝,依賴的任務(wù)才能算完成壮啊,這是一種可靠的任務(wù)序列。要么成功都成功撑蒜,失敗都失敗歹啼,兩個(gè)任務(wù)的狀態(tài)可以保持一致。而異步是不需要等待被依賴的任務(wù)完成减江,只是通知被依賴的任務(wù)要完成什么工作染突,依賴的任務(wù)也立即執(zhí)行,只要自己完成了整個(gè)任務(wù)就算完成了辈灼。至于被依賴的任務(wù)最終是否真正完成,依賴它的任務(wù)無(wú)法確定也榄,所以它是不可靠的任務(wù)序列巡莹。我們可以用打電話和發(fā)短信來(lái)很好的比喻同步與異步操作。

阻塞和非阻塞是針對(duì)CPU來(lái)說(shuō)的甜紫。阻塞與非阻塞主要是從 CPU 的消耗上來(lái)說(shuō)的降宅,阻塞就是 CPU 停下來(lái)等待一個(gè)慢的操作完成 CPU 才接著完成其它的事。非阻塞就是在這個(gè)慢的操作在執(zhí)行時(shí) CPU 去干其它別的事囚霸,等這個(gè)慢的操作完成時(shí)腰根,CPU 再接著完成后續(xù)的操作。雖然表面上看非阻塞的方式可以明顯的提高 CPU 的利用率拓型,但是也帶了另外一種后果就是系統(tǒng)的線程切換增加额嘿。增加的 CPU 使用時(shí)間能不能補(bǔ)償系統(tǒng)的切換成本需要好好評(píng)估瘸恼。

序列化

Java的對(duì)象序列化將那些實(shí)現(xiàn)了Serializable接口的對(duì)象轉(zhuǎn)換成一個(gè)字節(jié)序列,并能夠在以后將這個(gè)字節(jié)序列完全恢復(fù)為原來(lái)的對(duì)象册养。這一過(guò)程可通過(guò)網(wǎng)絡(luò)進(jìn)行东帅,這樣序列化機(jī)制能夠自動(dòng)彌補(bǔ)不同操作系統(tǒng)之間的差異。對(duì)應(yīng)序列化的聰明之處在于它不僅保存了對(duì)象的“全景圖”球拦,而且能夠追蹤到對(duì)象自所包含的引用靠闭,并保存這些對(duì)象;接著又能夠?qū)?duì)象內(nèi)包含的每個(gè)這樣的引用進(jìn)行最終坎炼;以此類推愧膀。

要實(shí)例化一個(gè)對(duì)象,首先創(chuàng)建某些OutputStream對(duì)象谣光,然后將其封裝在一個(gè)ObjectOutputStream對(duì)象內(nèi)扇调,這是,只需要調(diào)用writeObject()即可將對(duì)象序列化抢肛,并將其發(fā)送到OutputStream(對(duì)象序列化基于字節(jié)狼钮,因此使用InputStream和OutputStream繼承類層次結(jié)構(gòu))。反序列化和序列化過(guò)程正好相反捡絮,需要將一個(gè)InputStream封裝在ObjectInputStream內(nèi)熬芜,然后調(diào)用readObject()獲取一個(gè)引用,它指向一個(gè)向上轉(zhuǎn)型的Object福稳,所以必須向下轉(zhuǎn)型才能直接設(shè)置它們涎拉。

磁盤(pán) I/O 工作機(jī)制

前面介紹了基本的 Java I/O 的操作接口,這些接口主要定義了如何操作數(shù)據(jù)的圆,以及介紹了操作兩種數(shù)據(jù)結(jié)構(gòu):字節(jié)和字符的方式鼓拧。還有一個(gè)關(guān)鍵問(wèn)題就是數(shù)據(jù)寫(xiě)到何處,其中一個(gè)主要方式就是將數(shù)據(jù)持久化到物理磁盤(pán)越妈,下面將介紹如何將數(shù)據(jù)持久化到物理磁盤(pán)的過(guò)程季俩。

我們知道數(shù)據(jù)在磁盤(pán)的唯一最小描述就是文件,也就是說(shuō)上層應(yīng)用程序只能通過(guò)文件來(lái)操作磁盤(pán)上的數(shù)據(jù)梅掠,文件也是操作系統(tǒng)和磁盤(pán)驅(qū)動(dòng)器交互的一個(gè)最小單元酌住。

何時(shí)真正會(huì)要檢查一個(gè)文件存不存?就是在真正要讀取這個(gè)文件時(shí)阎抒,例如 FileInputStream 類都是操作一個(gè)文件的接口酪我,注意到在創(chuàng)建一個(gè) FileInputStream 對(duì)象時(shí),會(huì)創(chuàng)建一個(gè) FileDescriptor 對(duì)象且叁,其實(shí)這個(gè)對(duì)象就是真正代表一個(gè)存在的文件對(duì)象的描述都哭,當(dāng)我們?cè)诓僮饕粋€(gè)文件對(duì)象時(shí)可以通過(guò) getFD() 方法獲取真正操作的與底層操作系統(tǒng)關(guān)聯(lián)的文件描述。例如可以調(diào)用 FileDescriptor.sync() 方法將操作系統(tǒng)緩存中的數(shù)據(jù)強(qiáng)制刷新到物理磁盤(pán)中。

下面以清單 1 的程序?yàn)槔劢茫榻B下如何從磁盤(pán)讀取一段文本字符纱新。如下圖所示:

image

當(dāng)傳入一個(gè)文件路徑,將會(huì)根據(jù)這個(gè)路徑創(chuàng)建一個(gè) File 對(duì)象來(lái)標(biāo)識(shí)這個(gè)文件汇陆,然后將會(huì)根據(jù)這個(gè) File 對(duì)象創(chuàng)建真正讀取文件的操作對(duì)象怒炸,這時(shí)將會(huì)真正創(chuàng)建一個(gè)關(guān)聯(lián)真實(shí)存在的磁盤(pán)文件的文件描述符 FileDescriptor,通過(guò)這個(gè)對(duì)象可以直接控制這個(gè)磁盤(pán)文件毡代。由于我們需要讀取的是字符格式阅羹,所以需要 StreamDecoder 類將 byte 解碼為 char 格式,至于如何從磁盤(pán)驅(qū)動(dòng)器上讀取一段數(shù)據(jù)教寂,由操作系統(tǒng)幫我們完成捏鱼。

Java Socket 的工作機(jī)制

Socket 這個(gè)概念沒(méi)有對(duì)應(yīng)到一個(gè)具體的實(shí)體,它是描述計(jì)算機(jī)之間完成相互通信一種抽象功能酪耕。打個(gè)比方导梆,可以把 Socket 比作為兩個(gè)城市之間的交通工具,有了它迂烁,就可以在城市之間來(lái)回穿梭了看尼。交通工具有多種,每種交通工具也有相應(yīng)的交通規(guī)則盟步。Socket 也一樣藏斩,也有多種。大部分情況下我們使用的都是基于 TCP/IP 的流套接字却盘,它是一種穩(wěn)定的通信協(xié)議狰域。

下圖是典型的基于 Socket 的通信的場(chǎng)景:

image

主機(jī) A 的應(yīng)用程序要能和主機(jī) B 的應(yīng)用程序通信,必須通過(guò) Socket 建立連接黄橘,而建立 Socket 連接必須需要底層 TCP/IP 協(xié)議來(lái)建立 TCP 連接兆览。建立 TCP 連接需要底層 IP 協(xié)議來(lái)尋址網(wǎng)絡(luò)中的主機(jī)。我們知道網(wǎng)絡(luò)層使用的 IP 協(xié)議可以幫助我們根據(jù) IP 地址來(lái)找到目標(biāo)主機(jī)塞关,但是一臺(tái)主機(jī)上可能運(yùn)行著多個(gè)應(yīng)用程序抬探,如何才能與指定的應(yīng)用程序通信就要通過(guò) TCP 或 UPD 的地址也就是端口號(hào)來(lái)指定。這樣就可以通過(guò)一個(gè) Socket 實(shí)例唯一代表一個(gè)主機(jī)上的一個(gè)應(yīng)用程序的通信鏈路了描孟。

建立通信鏈路

當(dāng)客戶端要與服務(wù)端通信驶睦,客戶端首先要?jiǎng)?chuàng)建一個(gè) Socket 實(shí)例,操作系統(tǒng)將為這個(gè) Socket 實(shí)例分配一個(gè)沒(méi)有被使用的本地端口號(hào)匿醒,并創(chuàng)建一個(gè)包含本地和遠(yuǎn)程地址和端口號(hào)的套接字?jǐn)?shù)據(jù)結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)將一直保存在系統(tǒng)中直到這個(gè)連接關(guān)閉缠导。在創(chuàng)建 Socket 實(shí)例的構(gòu)造函數(shù)正確返回之前廉羔,將要進(jìn)行 TCP 的三次握手協(xié)議,TCP 握手協(xié)議完成后僻造,Socket 實(shí)例對(duì)象將創(chuàng)建完成憋他,否則將拋出 IOException 錯(cuò)誤孩饼。

與之對(duì)應(yīng)的服務(wù)端將創(chuàng)建一個(gè) ServerSocket 實(shí)例,ServerSocket 創(chuàng)建比較簡(jiǎn)單只要指定的端口號(hào)沒(méi)有被占用竹挡,一般實(shí)例創(chuàng)建都會(huì)成功镀娶,同時(shí)操作系統(tǒng)也會(huì)為 ServerSocket 實(shí)例創(chuàng)建一個(gè)底層數(shù)據(jù)結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)中包含指定監(jiān)聽(tīng)的端口號(hào)和包含監(jiān)聽(tīng)地址的通配符揪罕,通常情況下都是“*”即監(jiān)聽(tīng)所有地址梯码。之后當(dāng)調(diào)用 accept() 方法時(shí),將進(jìn)入阻塞狀態(tài)好啰,等待客戶端的請(qǐng)求轩娶。當(dāng)一個(gè)新的請(qǐng)求到來(lái)時(shí),將為這個(gè)連接創(chuàng)建一個(gè)新的套接字?jǐn)?shù)據(jù)結(jié)構(gòu)框往,該套接字?jǐn)?shù)據(jù)的信息包含的地址和端口信息正是請(qǐng)求源地址和端口鳄抒。這個(gè)新創(chuàng)建的數(shù)據(jù)結(jié)構(gòu)將會(huì)關(guān)聯(lián)到 ServerSocket 實(shí)例的一個(gè)未完成的連接數(shù)據(jù)結(jié)構(gòu)列表中,注意這時(shí)服務(wù)端與之對(duì)應(yīng)的 Socket 實(shí)例并沒(méi)有完成創(chuàng)建椰弊,而要等到與客戶端的三次握手完成后许溅,這個(gè)服務(wù)端的 Socket 實(shí)例才會(huì)返回,并將這個(gè) Socket 實(shí)例對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)從未完成列表中移到已完成列表中秉版。所以 ServerSocket 所關(guān)聯(lián)的列表中每個(gè)數(shù)據(jù)結(jié)構(gòu)贤重,都代表與一個(gè)客戶端的建立的 TCP 連接。

數(shù)據(jù)傳輸

傳輸數(shù)據(jù)是我們建立連接的主要目的沐飘,如何通過(guò) Socket 傳輸數(shù)據(jù)游桩,下面將詳細(xì)介紹。

當(dāng)連接已經(jīng)建立成功耐朴,服務(wù)端和客戶端都會(huì)擁有一個(gè) Socket 實(shí)例借卧,每個(gè) Socket 實(shí)例都有一個(gè) InputStream 和 OutputStream,正是通過(guò)這兩個(gè)對(duì)象來(lái)交換數(shù)據(jù)筛峭。同時(shí)我們也知道網(wǎng)絡(luò) I/O 都是以字節(jié)流傳輸?shù)念砹酢.?dāng) Socket 對(duì)象創(chuàng)建時(shí),操作系統(tǒng)將會(huì)為 InputStream 和 OutputStream 分別分配一定大小的緩沖區(qū)影晓,數(shù)據(jù)的寫(xiě)入和讀取都是通過(guò)這個(gè)緩存區(qū)完成的镰吵。寫(xiě)入端將數(shù)據(jù)寫(xiě)到 OutputStream 對(duì)應(yīng)的 SendQ 隊(duì)列中,當(dāng)隊(duì)列填滿時(shí)挂签,數(shù)據(jù)將被發(fā)送到另一端 InputStream 的 RecvQ 隊(duì)列中疤祭,如果這時(shí) RecvQ 已經(jīng)滿了,那么 OutputStream 的 write 方法將會(huì)阻塞直到 RecvQ 隊(duì)列有足夠的空間容納 SendQ 發(fā)送的數(shù)據(jù)饵婆。值得特別注意的是勺馆,這個(gè)緩存區(qū)的大小以及寫(xiě)入端的速度和讀取端的速度非常影響這個(gè)連接的數(shù)據(jù)傳輸效率,由于可能會(huì)發(fā)生阻塞,所以網(wǎng)絡(luò) I/O 與磁盤(pán) I/O 在數(shù)據(jù)的寫(xiě)入和讀取還要有一個(gè)協(xié)調(diào)的過(guò)程草穆,如果兩邊同時(shí)傳送數(shù)據(jù)時(shí)可能會(huì)產(chǎn)生死鎖灌灾,在后面 NIO 部分將介紹避免這種情況。

20190111143019.png

代碼傳送門(mén)
FileUtils
FileIOUtils

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悲柱,一起剝皮案震驚了整個(gè)濱河市锋喜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌豌鸡,老刑警劉巖嘿般,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異直颅,居然都是意外死亡博个,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)功偿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盆佣,“玉大人,你說(shuō)我怎么就攤上這事械荷」菜#” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵吨瞎,是天一觀的道長(zhǎng)痹兜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)颤诀,這世上最難降的妖魔是什么字旭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮崖叫,結(jié)果婚禮上遗淳,老公的妹妹穿的比我還像新娘。我一直安慰自己心傀,他們只是感情好屈暗,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著脂男,像睡著了一般养叛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宰翅,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天弃甥,我揣著相機(jī)與錄音,去河邊找鬼汁讼。 笑死潘飘,一個(gè)胖子當(dāng)著我的面吹牛肮之,可吹牛的內(nèi)容都是我干的掉缺。 我是一名探鬼主播卜录,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼眶明!你這毒婦竟也來(lái)了艰毒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤搜囱,失蹤者是張志新(化名)和其女友劉穎丑瞧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蜀肘,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绊汹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扮宠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片西乖。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坛增,靈堂內(nèi)的尸體忽然破棺而出获雕,到底是詐尸還是另有隱情,我是刑警寧澤收捣,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布届案,位于F島的核電站,受9級(jí)特大地震影響罢艾,放射性物質(zhì)發(fā)生泄漏楣颠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一咐蚯、第九天 我趴在偏房一處隱蔽的房頂上張望童漩。 院中可真熱鬧,春花似錦仓蛆、人聲如沸睁冬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)豆拨。三九已至,卻和暖如春能庆,著一層夾襖步出監(jiān)牢的瞬間施禾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工搁胆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弥搞,地道東北人邮绿。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像攀例,于是被迫代替她去往敵國(guó)和親船逮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容