【Java】I/O流之字节流
一、什么是字節(jié)流
二、字節(jié)輸出流
1. 創(chuàng)建一個(gè)字節(jié)輸出流對象
2. 寫入數(shù)據(jù)
3. 換行
4. 追加寫入
三、字節(jié)輸入流
1. 創(chuàng)建一個(gè)字節(jié)輸入流對象
2. 讀取數(shù)據(jù)
四、利用字節(jié)輸入輸出流復(fù)制一個(gè)文件
五、以字節(jié)數(shù)組形式讀取
一、什么是字節(jié)流
電腦中存儲(chǔ)的文件都是以二進(jìn)制以字節(jié)為單位的形式保存,在傳輸時(shí)也是按字節(jié)傳輸。所以說,字節(jié)流可以讀取以及傳輸任意格式的文件數(shù)據(jù)。
注意:在創(chuàng)建字節(jié)流時(shí),每創(chuàng)建一個(gè)字節(jié)流對象都要在最后關(guān)閉流。如果操作比較頻繁并且不對流進(jìn)行關(guān)閉,很容易就出現(xiàn)輸入輸出流超越JVM的邊界,所以有時(shí)候就可能無法回收資源。而且不關(guān)閉流時(shí),如果在操作系統(tǒng)里對這個(gè)文件進(jìn)行刪除等操作時(shí)就會(huì)報(bào)錯(cuò),顯示該文件正在被某個(gè)進(jìn)程占用。
流關(guān)閉原則:先開后關(guān),后開先關(guān)。
二、字節(jié)輸出流
目的:向文件中寫入數(shù)據(jù)
1. 創(chuàng)建一個(gè)字節(jié)輸出流對象
FileOutputStream fw = new FileOutputStream("text.txt");2. 寫入數(shù)據(jù)
字節(jié)流寫入數(shù)據(jù)時(shí)操縱的是ASCII碼,即代碼層面寫的數(shù)據(jù)為所要寫入字符的ASCII碼,例如寫入字符A時(shí)就要write(65).
(1)以單個(gè)字節(jié)形式寫入
fw.write(65);//數(shù)字代表的ASCII碼,寫入的是ASCII碼對應(yīng)的字符 fw.write(66); fw.write(67); fw.write(68); fw.write(69);(2)以字節(jié)數(shù)組形式寫入
byte[] by = {97,98,99,100,101}; fw.write(by);如果覺得ASCII碼記不住可以利用getBytes()方法,將字符內(nèi)容自動(dòng)轉(zhuǎn)換為ASCII碼
byte[] bys = "12345678".getBytes();//直接將字符轉(zhuǎn)換為字體默認(rèn)的編碼格式 fw.write(bys);(3)寫入字節(jié)數(shù)組中指定范圍的內(nèi)容
byte[] by = {97,98,99,100,101}; fw.write(by, 1, 3);//寫入字節(jié)數(shù)組中指定范圍的內(nèi)容??
3. 換行
????????我們上面的方法在寫入數(shù)據(jù)時(shí)都是一行一行的寫滿才會(huì)換下一行,那么當(dāng)我們需要主動(dòng)換行時(shí)該怎么辦呢?接下來就讓我們一起看看。
? ? ? ? 現(xiàn)在我們已經(jīng)知道字節(jié)流寫入字符時(shí)都是按其ASCII碼寫入,那么相應(yīng)的,換行符‘\n’也有對應(yīng)的ASCII碼,所以我們只要在寫入時(shí)傳入換行符的ASCII碼就能實(shí)現(xiàn)換行操作。?
fw.write("12345\n6789".getBytes());在這里要注意一點(diǎn),不用的設(shè)備系統(tǒng)得換行符標(biāo)識(shí)不同
windows:\r或\n ? ?Linux:\n ? ?Mac:\r
4. 追加寫入
????????以上的寫入方法都是在文件中從頭寫入,會(huì)覆蓋原有的文件內(nèi)容,那么如果我們只想在原有內(nèi)容后追加內(nèi)容怎么辦呢?
? ? ? ? 這是就要回到我們創(chuàng)建輸出流對象的時(shí)候了,系統(tǒng)默認(rèn)的創(chuàng)建是不追加,直接從頭開始寫數(shù)據(jù),我們只需要在創(chuàng)建對象時(shí)加入?yún)?shù)true,就可以實(shí)現(xiàn)追加寫入了。
FileOutputStream fw1 = new FileOutputStream("text.txt",true); fw1.write("\nHolle World".getBytes()); fw1.close();三、字節(jié)輸入流
1. 創(chuàng)建一個(gè)字節(jié)輸入流對象
FileInputStream fr = new FileInputStream("text.txt");2. 讀取數(shù)據(jù)
原數(shù)據(jù)內(nèi)容為“ABC”
System.out.println(fr.read());通過輸出可以看到讀取的為對應(yīng)的ASCII,那么怎么讓其輸出字符呢?我們可以利用char強(qiáng)制轉(zhuǎn)換。
int b =fr.read(); System.out.println((char)b+":"+b);//輸出字符及對應(yīng)的ASCII碼,一次只能讀一個(gè)字符現(xiàn)在已經(jīng)能夠讀取并且輸出字符了,可還有一個(gè)問題,write方法一次只能讀取一個(gè)字符,要怎么才能一次讀取全部字符呢?我們可以利用循環(huán)來反復(fù)多次讀取,但是讀取停止的條件又是什么呢?讓我們多讀取幾個(gè)字符看看。?
int b =fr.read(); System.out.println((char)b+":"+b);//輸出字符及對應(yīng)的ASCII碼,一次只能讀一個(gè)字符//多讀取幾次數(shù)據(jù),發(fā)現(xiàn)數(shù)據(jù)讀完時(shí)返回結(jié)果為-1 b =fr.read(); System.out.println((char)b+":"+b); b =fr.read(); System.out.println((char)b+":"+b); b =fr.read(); System.out.println((char)b+":"+b);通過輸出結(jié)果可以看到當(dāng)所有內(nèi)容都被讀取完時(shí)返回的ASCII碼為-1?,這樣我們就有了循環(huán)停止的條件,即read返回的值為-1時(shí)就停止循環(huán)。
int by; while((by = fr.read()) != -1) {System.out.print((char)by); }四、利用字節(jié)輸入輸出流復(fù)制一個(gè)文件
要求:將一個(gè)文件中的內(nèi)容復(fù)制到另一個(gè)文件
思路:每讀一次數(shù)據(jù)就寫一次,然后再讀下一次,直到讀完
代碼:
FileInputStream fr = new FileInputStream("text.txt"); FileOutputStream fr1 = new FileOutputStream("text1.txt");int by; while((by = fr.read()) != -1) {System.out.print((char)by);fr1.write(by); } fr1.close(); fr.close();控制臺(tái)輸出:
?原文件與復(fù)制文件:
五、以字節(jié)數(shù)組形式讀取
????????上面我們讀取內(nèi)容時(shí)都是以單個(gè)字符的形式讀取,即對于每個(gè)字符都要開關(guān)一次讀操作,除此之外還可以以字符數(shù)組的形式讀取,即對于一定數(shù)量的字符進(jìn)行一次讀取操作。就好比有一隊(duì)人要通一扇門,一般的讀取就是每個(gè)人通過時(shí)都要開一次門再關(guān)上,而以數(shù)組形式讀取就是每開一次門后通過一定數(shù)量的人之后再關(guān)門等待下一波人通過。這樣可以大大的減少讀寫的速度。
下面我們做了一次實(shí)驗(yàn),利用兩種不同的讀取方法對一個(gè)220M大小的文件讀取,比較其花費(fèi)的時(shí)間。
以字節(jié)數(shù)組形式讀取:?
?以單個(gè)字節(jié)形式讀取:
?通過上面的實(shí)驗(yàn)我們可以看到,以字節(jié)數(shù)組形式讀取文件花費(fèi)的時(shí)間為514ms,大約為0.5秒,而以單個(gè)字節(jié)形式讀取文件花費(fèi)的時(shí)間為530332ms,大約為8.84分鐘,后者花費(fèi)時(shí)間為前者的1000多倍,可見差距之大。
總結(jié)
以上是生活随笔為你收集整理的【Java】I/O流之字节流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦幻西游手游转区没服务器显示不出来,梦幻
- 下一篇: Chrome书签整理