JAVA IO流最詳解
? (轉自CSDN)
IO流上:概述、字符流、緩沖區(java基礎)
? 一、IO流概述
概述:
???????? IO流簡單來說就是Input和Output流,IO流主要是用來處理設備之間的數據傳輸,Java對于數據的操作都是通過流實現,而java用于操作流的對象都在IO包中。
分類:
??????? 按操作數據分為:字節流和字符流。 如:Reader和InpurStream
??????? 按流向分:輸入流和輸出流。如:InputStream和OutputStream
IO流常用的基類:
???????? * InputStream??? ,??? OutputStream
字符流的抽象基類:
???????? * Reader?????? ,???????? Writer
由上面四個類派生的子類名稱都是以其父類名作為子類的后綴:
??????????? 如:FileReader和FileInputStream
二、字符流
1. 字符流簡介:
* 字符流中的對象融合了編碼表,也就是系統默認的編碼表。我們的系統一般都是GBK編碼。
* 字符流只用來處理文本數據,字節流用來處理媒體數據。
* 數據最常見的表現方式是文件,字符流用于操作文件的子類一般是FileReader和FileWriter。
2.字符流讀寫:
注意事項:
* 寫入文件后必須要用flush()刷新。
* 用完流后記得要關閉流
* 使用流對象要拋出IO異常
?
*?定義文件路徑時,可以用“/”或者“\\”。
*?在創建一個文件時,如果目錄下有同名文件將被覆蓋。
*?在讀取文件時,必須保證該文件已存在,否則出異常
示例1:在硬盤上創建一個文件,并寫入一些文字數據
?
[java]?view plaincopy
class?FireWriterDemo?{??????public?static?void?main(String[]?args)?throws?IOException?{?????????????????????????????????????????FileWriter?fw?=?new?FileWriter("F:\\1.txt");??????????????????fw.write("hello?world!");????????????????????????fw.flush();????????????????????fw.write("first_test");??????????fw.close();????????????????}??}?? ?
示例2:FileReader的reade()方法.
要求:用單個字符和字符數組進行分別讀取
?
[java]?view plaincopy
class?FileReaderDemo?{??????public?static?void?main(String[]?args)?{??????????characters();??????}??????????private?static?void?characters()?{????????????try?{????????????????FileReader?fr?=?new?FileReader("Demo.txt");??????????????char?[]??buf?=?new?char[6];???????????????????????????int?num?=?0;??????????????????while((num?=?fr.read(buf))!=-1)?{????????????????????????????????????sop(new?String(buf,0,num));??????????????}??????????????sop('\n');??????????????fr.close();??????????}??????????catch?(IOException?e)?{??????????????sop(e.toString());??????????}??????}??????????????????private?static?void?singleReader()?{????????????????????try?{????????????????????????????????????????FileReader?fr?=?new?FileReader("Demo.txt");??????????????????????????????????????????????????int?ch?=?0;??????????????while?((ch=fr.read())!=-1)?{??????????????????sop((char)ch);??????????????}??????????????sop('\n');??????????????fr.close();????????????????????????????????????????????}??????????catch?(IOException?e)?{??????????????sop(e.toString());??????????}????????????}??????????private?static?void?sop(Object?obj)?{??????????System.out.print(obj);??????}????}?? ?
示例3:對已有文件的數據進行續寫
?
?
[java]?view plaincopy
import?java.io.*;????class??FileWriterDemo3?{??????public?static?void?main(String[]?args)?{????????????????????try?{??????????????????????????FileWriter?fw?=?new?FileWriter("F:\\java_Demo\\day9_24\\demo.txt",true);??????????????fw.write("?is?charactor?table?");??????????????fw.close();??????????}??????????catch?(IOException?e)?{??????????????sop(e.toString());??????????}????????????????}????????private?static?void?sop(Object?obj)??????{??????????System.out.println(obj);??????}??}?? ?
練習:
將F盤的一個文件復制到E盤。?
思考:
其實就是將F盤下的文件數據存儲到D盤的一個文件中。
步驟:
1.在D盤創建一個文件,存儲F盤中文件的數據。
2.定義讀取流和F:盤文件關聯。
3.通過不斷讀寫完成數據存儲。
4.關閉資源。
源碼:
?
[java]?view plaincopy
import?java.io.*;??import?java.util.Scanner;????class?CopyText?{??????public?static?void?main(String[]?args)?throws?IOException?{??????????sop("請輸入要拷貝的文件的路徑:");??????????Scanner?in?=?new?Scanner(System.in);??????????String?source?=?in.next();??????????sop("請輸入需要拷貝到那個位置的路徑以及生成的文件名:");??????????String?destination?=?in.next();??????????in.close();??????????CopyTextDemo(source,destination);????????}????????private?static?void?CopyTextDemo(String?source,String?destination)?{????????????try?{??????????????FileWriter?fw?=?new?FileWriter(destination);??????????????FileReader?fr?=?new?FileReader(source);??????????????char?[]??buf?=?new?char[1024];???????????????????????????int?num?=?0;??????????????????while((num?=?fr.read(buf))!=-1)?{?????????????????????????????????????????????????fw.write(new?String(buf,0,num));??????????????}??????????????fr.close();??????????????fw.close();??????????}??????????catch?(IOException?e)?{??????????????sop(e.toString());??????????}??????}????????????private?static?void?sop(Object?obj)?{??????????System.out.println(obj);??????}??}?? ?
三、緩沖區
1. 字符流的緩沖區:BufferedReader和BufferedWreiter
* 緩沖區的出現時為了提高流的操作效率而出現的.
* 需要被提高效率的流作為參數傳遞給緩沖區的構造函數
* 在緩沖區中封裝了一個數組,存入數據后一次取出
BufferedReader示例:
讀取流緩沖區提供了一個一次讀一行的方法readline,方便對文本數據的獲取。
readline()只返回回車符前面的字符,不返回回車符。如果是復制的話,必須加入newLine(),寫入回車符
newLine()是java提供的多平臺換行符寫入方法。
?
[java]?view plaincopy
import?java.io.*;??????class?BufferedReaderDemo?{??????public?static?void?main(String[]?args)??throws?IOException?{????????????????????FileReader?rw?=?new?FileReader("buf.txt");????????????????????BufferedReader?brw?=?new?BufferedReader(rw);??????????????????????for(;;)?{??????????????String?s?=?brw.readLine();??????????????if(s==null)?break;??????????????System.out.println(s);??????????}????????????????????brw.close();??????}??}?? ?
BufferedWriter示例:
?
[java]?view plaincopy
import?java.io.*;??????class?BufferedWriterDemo?{??????public?static?void?main(String[]?args)??throws?IOException?{????????????????????FileWriter?fw?=?new?FileWriter("buf.txt");????????????????????????????BufferedWriter?bfw?=?new?BufferedWriter(fw);????????????????????????????????????for(int?x?=?1;?x?<?5;?x++)?{??????????????bfw.write("abc");??????????????bfw.newLine();??????????????????????????????bfw.flush();??????????}????????????????bfw.flush();????????????????????????????????????????????????????????bfw.close();??????????????????????????????????????????????????????????????????fw.close();???????????????????????????????????????????????????????}??}?? ?
2.裝飾設計模式
裝飾設計模式::::
要求:自定義一些Reader類,讀取不同的數據(裝飾和繼承的區別)
MyReader //專門用于讀取數據的類
?? ?|--MyTextReader
?? ??? ?|--MyBufferTextReader
?? ?|--MyMediaReader
?? ??? ?|--MyBufferMediaReader
?? ?|--MyDataReader
?? ??? ?|--MyBufferDataReader
如果將他們抽取出來,設計一個MyBufferReader,可以根據傳入的類型進行增強
class MyBufferReader {
?? ?MyBufferReader (MyTextReader text) {}
?? ?MyBufferReader (MyMediaReader media) {}
?? ?MyBufferReader (MyDataReader data) {}
}
但是上面的類拓展性很差。找到其參數的共同類型,通過多態的形式,可以提高拓展性
class MyBufferReader? extends MyReader{
?? ?private MyReader r;?? ??? ??? ??? ??? ??? ?//從繼承變為了組成模式? 裝飾設計模式
?? ?MyBufferReader(MyReader r) {}
}
優化后的體系:
?? ?|--MyTextReader
?? ?|--MyMediaReader
?? ?|--MyDataReader
?? ?|--MyBufferReader?? ??? ?//增強上面三個。裝飾模式比繼承靈活,
?? ??? ??? ??? ??? ??? ??? ?? 避免繼承體系的臃腫。降低類與類之間的耦合性
裝飾類只能增強已有的對象,具備的功能是相同的。所以裝飾類和被裝飾類屬于同一個體系
?
?
?
MyBuffereReader類:? 自己寫一個MyBuffereReader類,功能與BuffereReader相同
?
[java]?view plaincopy
class?MyBufferedReader1??extends?Reader{???????????????????private?Reader?r;??????MyBufferedReader1(Reader?r){??????????this.r??=?r;??????}????????????public?String?myReaderline()??throws?IOException?{??????????????????????????StringBuilder?sb?=?new?StringBuilder();??????????int?ch?=?0;??????????while((ch?=?r.read())?!=?-1)??????????{??????????????if(ch?==?'\r')???????????????????continue;??????????????if(ch?==?'\n')????????????????????????????????????return?sb.toString();??????????????else??????????????sb.append((char)ch);??????????}??????????if(sb.length()!=0)????????????????????????????????return?sb.toString();??????????return?null;??????}??????????public?void?close()throws?IOException?{??????????r.close();??????}????????public?int?read(char[]?cbuf,int?off,?int?len)throws?IOException?{???????????return?r.read(cbuf,off,len);??????}????????public?void?myClose()?throws?IOException{??????????r.close();??????}??????}?? ?
?
?
一、字節流
1.概述:
?
1、字節流和字符流的基本操作是相同的,但是要想操作媒體流就需要用到字節流。
2、字節流因為操作的是字節,所以可以用來操作媒體文件。(媒體文件也是以字節存儲的)
3、讀寫字節流:InputStream???輸入流(讀)和OutputStream??輸出流(寫)
4、字節流操作可以不用刷新流操作。
5、InputStream特有方法:
? ????? int available();//返回文件中的字節個數
注:可以利用此方法來指定讀取方式中傳入數組的長度,從而省去循環判斷。但是如果文件較大,而虛擬機啟動分配的默認內存一般為64M。當文件過大時,此數組長度所占內存空間就會溢出。所以,此方法慎用,當文件不大時,可以使用。
練習:
需求:復制一張圖片F:\java_Demo\day9_28\1.BMP到F:\java_Demo\day9_28\2.bmp
?
[java]?view plaincopy
import?java.io.*;??????class?CopyPic?{??????public?static?void?main(String[]?args){??????????copyBmp();??????????System.out.println("復制完成");??????}????????public?static?void?copyBmp()?{????????????FileInputStream?fis?=?null;??????????FileOutputStream?fos?=?null;??????????try?{??????????????fis?=?new?FileInputStream("F:\\java_Demo\\day9_28\\1.bmp");?????????????????????????fos?=?new?FileOutputStream("F:\\java_Demo\\day9_28\\2.bmp");????????????????????????byte[]?copy?=?new?byte[1024];??????????????int?len?=?0;??????????????while((len=fis.read(copy))!=-1)?{??????????????fos.write(copy,0,len);??????????????}??????????}??????????catch?(IOException?e)?{??????????????e.printStackTrace();??????????????throw?new?RuntimeException("復制文件異常");??????????}??????????finally?{??????????????try?{??????????????????if(fis!=null)?fis.close();??????????????}??????????????catch?(IOException?e)?{??????????????????e.printStackTrace();??????????????????throw?new?RuntimeException("讀取流");??????????????}??????????}????????????????}????}?? ?
2. 字節流緩沖區
* 字節流緩沖區跟字符流緩沖區一樣,也是為了提高效率。
注意事項:
1. read():會將字節byte()提升為int型值
2. write():會將int類型轉換為byte()類型,保留最后的8位。
練習:
1.復制MP3文件?? 1.MP3 -->? 2.MP3
2.自己寫一個MyBufferedInputStream緩沖類,提升復制速度
代碼:
?
[java]?view plaincopy
import?java.io.*;??????class?MyBufferedInputStream??{??????private?InputStream?in;?????????????????????????????private?byte?[]?buf?=?new?byte[1024*4];??????private?int?count?=?0,pos?=?0;??????public?MyBufferedInputStream(InputStream?in){??????????this.in?=?in;??????}????????public??int?MyRead()?throws?IOException{??????????if(count==0)?{??????????????????????????count?=?in.read(buf);??????????????pos?=?0;??????????????byte?b?=?buf[pos];??????????????count--;??????????????pos++;??????????????return?b&255;???????????????}??????????else?if(count?>?0)?{??????????????byte?b?=?buf[pos];??????????????pos++;??????????????count--;??????????????return?b&0xff;??????????????}??????????return?-1;??????}????????public?void?myClose()?throws?IOException{??????????in.close();??????}????}??????????class?BufferedCopyDemo?{??????public?static?void?main(String[]?args)?{??????????long?start?=?System.currentTimeMillis();??????????copy();??????????long?end?=?System.currentTimeMillis();??????????System.out.println("時間:"+(end-start)+"ms");??????????????start?=?System.currentTimeMillis();??????????copy1();??????????end?=?System.currentTimeMillis();??????????System.out.println("時間:"+(end-start)+"ms");??????}?????public?static?void?copy1()?{??????????????????????????MyBufferedInputStream?bis?=?null;??????????BufferedOutputStream??bos?=?null;??????????try?{??????????????bis?=?new?MyBufferedInputStream(new?FileInputStream("馬旭東-入戲太深.mp3"));????????????bos?=?new?BufferedOutputStream(new?FileOutputStream("3.mp3"));??????????????int?buf?=?0;??????????????while((buf=bis.MyRead())!=-1)?{??????????????????bos.write(buf);??????????????}??????????}??????????catch?(IOException?e)?{??????????????e.printStackTrace();??????????????throw?new?RuntimeException("復制失敗");??????????}??????????finally?{??????????????try?{??????????????????if(bis!=null)??{??????????????????????bis.myClose();??????????????????????bos.close();??????????????????}??????????????}??????????????catch?(IOException?e)?{??????????????????e.printStackTrace();??????????????}????????????}????????}??}??? ?
二、流操作規律
1. 鍵盤讀取,控制臺打印。
System.out: 對應的標準輸出設備:控制臺? //它是PrintStream對象,(PrintStream:打印流。OutputStream的子類)
System.in: 對應的標準輸入設備:鍵盤???? //它是InputStream對象
示例:
?
[java]?view plaincopy
????public?static?void?InOutDemo(){??????????????????BufferedReader?bufr?=?null;??????????BufferedWriter?bufw?=?null;??????????try?{????????????????????????????????????????????????????????bufr?=?new?BufferedReader(new?InputStreamReader(System.in));????????????????????????bufw?=?new?BufferedWriter(new?OutputStreamWriter(System.out));??????????????????String?line?=?null;??????????????while((line?=?bufr.readLine())!=null){??????????????????if("over".equals(line))?break;??????????????????bufw.write(line.toUpperCase());?????????????????????????????????????bufw.newLine();?????????????????????????????????????????????????????bufw.flush();???????????????????????????????????????????????????}??????????????if(bufw!=null)?{??????????????????bufr.close();??????????????????bufw.close();??????????????}??????????}??????????catch?(IOException?e)?{??????????????e.printStackTrace();??????????}??????????????????????????????}??}?? ?
2. 整行錄入
1.從鍵盤錄入數據,并存儲到文件中。
2. 我們在鍵盤錄入的是時候,read()方法是一個一個錄入的,能不能整行的錄入呢?這時候我們想到了BufferedReader中ReadLine()方法。
3. 轉換流
為了讓字節流可以使用字符流中的方法,我們需要轉換流。
?1. InputStreamReader:字節流轉向字符流;
a、獲取鍵盤錄入對象。
?????? ?????? InputStream in=System.in;
? b、將字節流對象轉成字符流對象,使用轉換流。
????????????? InputStreamReaderisr=new InputStreamReader(in);
? c、為了提高效率,將字符串進行緩沖區技術高效操作。使用BufferedReader
????????????? BufferedReaderbr=new BufferedReader(isr);
//鍵盤錄入最常見寫法
????????????? BufferedReaderin=new BufferedReader(new InputStreamReader(System.in));
2.OutputStreamWriter:字符流通向字節流
示例:
?
[java]?view plaincopy
????public?static?void?inToFile()?{??????????????????????BufferedReader?bufr?=?null;??????????BufferedWriter?bufw?=?null;??????????try?{????????????????????????????????????????????????????????bufr?=?new?BufferedReader(new?InputStreamReader(System.in));????????????????????????bufw?=?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream("out.txt")));?????????????????String?line?=?null;??????????????while((line?=?bufr.readLine())!=null){??????????????????if("over".equals(line))?break;??????????????????bufw.write(line.toUpperCase());?????????????????????????????????????bufw.newLine();?????????????????????????????????????????????????????bufw.flush();???????????????????????????????????????????????????}??????????????if(bufw!=null)?{??????????????????bufr.close();??????????????????bufw.close();??????????????}??????????}??????????catch?(IOException?e)?{??????????????e.printStackTrace();??????????}??????????????????????}?? ?
4. 流操作基本規律
為了控制格式我將其寫入了Java代碼段中,如下:
示例1:文本 ~ 文本
?
?
[java]?view plaincopy
/*??流操作的基本規律。??一、兩個明確:(明確體系)??1.?明確源和目的??????源:輸入流??InputStream??Reader??????目的:輸出流??OutputStream?Writer????2.?操作的數據是否是純文本??????是:?字符流??????否:?字節流??二、明確體系后要明確具體使用的對象??????通過設備區分:內存,硬盤,鍵盤??????目的設備:內存,硬盤,控制臺??????示例1:將一個文本文件中的數據存儲到另一個文件中:?復制文件??????一、明確體系??????????源:文件-->讀取流-->(InputStream和Reader)??????????是否是文本:是-->Reader??????????????????????????????目的:文件-->寫入流-->(OutputStream?Writer)??????????是否純文本:是-->Writer????????????二、?明確設備??????????源:Reader??????????????設備:硬盤上一個文本文件?-->?子類對象為:FileReader??????????????????FileReader?fr?=?new?FileReader("Goods.txt");????????????????????????????是否提高效率:是-->加入Reader中的緩沖區:BufferedReader??????????????????BufferedReader?bufr?=?new?BufferedReader(fr);????????????????????????????目的:Writer??????????????設備:鍵盤上一個文本文件?-->?子類對象:FileWriter??????????????????FileWriter?fw?=?new?FileWriter("goods1.txt");??????????????是否提高效率:是-->加入Writer的緩沖區:BufferedWriter??????????????????BufferedWriter?bufw?=?new?BufferedWriter(fw);????????????????????????????????????????????示例2:將一個圖片文件數據復制到另一個文件中:復制文件??????一、明確體系??????????源:文件-->讀取流-->(InputStream和Reader)??????????是否是文本:否-->InputStream??????????????????????????????目的:文件-->寫入流-->(OutputStream?Writer)??????????是否純文本:否-->OutputStream????????????二、?明確設備??????????源:InputStream??????????????設備:硬盤上一個媒體文件?-->?子類對象為:FileInputStream??????????????????FileInputStream?fis?=?new?FileInputStream("Goods.txt");????????????????????????????是否提高效率:是-->加入InputStream中的緩沖區:BufferedInputStream??????????????????BufferedInputStream?bufi?=?new?BufferedInputStream(fis);????????????????????????????目的:OutputStream??????????????設備:鍵盤上一個媒體文件?-->?子類對象:FileOutputStream??????????????????FileOutputStream?fos?=?new?FileOutputStream("goods1.txt");??????????????是否提高效率:是-->加入OutputStream的緩沖區:BufferedOutputStream??????????????????BufferedOutputStream?bufo?=?new?BufferedOutputStream(fw);????示例3:將鍵盤錄入的數據保存到一個文本文件中??????一、明確體系??????????源:鍵盤-->讀取流-->(InputStream和Reader)??????????是否是文本:是-->Reader??????????????????????????????目的:文件-->寫入流-->(OutputStream?Writer)??????????是否純文本:是-->Writer????????????二、?明確設備??????????源:InputStream??????????????設備:鍵盤?-->?對用對象為:System.in?-->?InputStream??????????????????為了操作方便,轉成字符流Reader?-->?使用Reader中的轉換流:InputStreamReader??????????????????InputStreamReader?isr?=?new?InputStreamReader(System.in);????????????????????????????是否提高效率:是-->加入Reader中的緩沖區:BufferedReader??????????????????BufferedReader?bufr?=?new?BufferedReader(isr);????????????????????????????目的:Writer??????????????設備:鍵盤上一個文本文件?-->?子類對象:FileWriter??????????????????FileWriter?fw?=?new?FileWriter("goods1.txt");??????????????是否提高效率:是-->加入Writer的緩沖區:BufferedWriter??????????????????BufferedWriter?bufw?=?new?BufferedWriter(fw);?? 5.指定編碼表(轉換流可以指定編碼表)
要求:用UTF-8編碼存儲一個文本文件
?
[java]?view plaincopy
import?java.io.*;??public?class?IOStreamLaw?{????????????public?static?void?main(String[]?args)?throws?IOException?{??????????????????????????????????BufferedReader?bufr?=?new?BufferedReader(new?InputStreamReader(System.in));??????????????????BufferedWriter?bufw?=?new?BufferedWriter(new?OutputStreamWriter(new?FileOutputStream("goods1.txt"),"UTF-8"));??????????????????String?line?=?null;??????????????????while((line=bufr.readLine())!=null){??????????????????????if("over".equals(line))?break;??????????????????????bufw.write(line.toUpperCase());??????????????????????bufw.newLine();??????????????????????bufw.flush();??????????????????}??????????????????bufr.close();??????}??????}?? Java NIO流
? ? ?對于JavaNIO還是不是很了解,之前認為NIO的N是non-block IO的意思,非阻塞;但是原來是New IO的意思。這個新表示的是和原來的BIO而言是一種新的IO吧。NIO的主要特性就是緩沖區,通道,和選擇器(這個可能不是)。
? ? ? Java在JDK1.4版本呢,引入了NIO這個新的api。Sun公司官方說明NIO的特性如下:
1. 為所有的原始類型提供了(Buffer)緩存支持;
2. 字符集編碼解碼解決方案
3. Channel(通道):一個新的原始I/O抽象;
4. 支持鎖和內存映射文件的文件訪問接口;
5. 提供多路(non-blocking)非阻塞式的高伸縮網絡I/O。
? ? ? 對于上面的特性,我是不大了解的。不過,不影響,我們繼續介紹。
? ? ? NIO創建的目的是,實現高速的I/O,而無需編寫自定義的本機代碼。
? ? ? 那NIO大概是怎么做到的呢?它將最耗時的I/O操作轉回操作系統,因而可以極大的提高速度。而最耗時的I/O操作是填充和提取緩沖區。
? ? ? 原來的io和現在NIO最重要的區別就是,數據打包和傳輸的方式。以前是以流,現在是以塊的方式處理數據。
? ? ? 之前用流的方式呢,只能一次一個字節的處理數據。一個輸入流產生一個字節的數據,而一個輸出流則消耗一個字節的數據。這樣的好處是,創建過濾器特別容易,可以創建多個過濾器,每個過濾器處理只處理一部分的數據。壞處就是,比較慢。
? ? ? 而NIO用塊的方式呢,可以一次一個塊的處理數據。每一步的操作都在產生或者消耗一個塊,好處是相對于流快得多,壞處是,不夠優雅和簡單。
緩沖區
? ? ? 然后開始介紹緩沖區,緩沖區就是上面介紹到的NIO的特性第一條,為所有的原始數據都提供了Buffer緩存的支持。它主要是將所有的原始數據放在數組中,以塊的形式處理。
? ? ??而每種緩沖區的類都有四個屬性:容量(Capacity),上界(Limit),位置(Position),以及標記(Mark),用于提供關于其所包含的數據元素的信息。
? ? ? 容量:緩沖區能夠容納的數據元素的最大數量,緩沖區創建時確定,永遠不能被改變;
? ? ? 上界:緩沖區第一個不能被讀或寫的元素,或者說,緩沖區現存元素的計數。
? ? ? 位置:下一個要被讀或寫的元素的索引。該值會自動由相應的get(),put()函數更新;
? ? ? 標記:一個備忘的位置。調用mark()來設定mark=position。調用reset()來設定position = mark;標記在設定前是未定義的undefined。
? ? ? 緩沖區的分類有,ByteBuffer(字節緩沖區),CharBuffer(字符緩沖區),ShortBuffer(短整型緩沖區),IntBuffer(整型緩沖區),LongBuffer(長整型緩沖區),FloatBuffer(單精度浮點緩沖區),DoubleBuffer(雙精度浮點緩沖區),就是沒有布爾緩沖區。
? ? ? 他們都是抽象類,所以不能實例化,然后他們都繼承了Buffer類,所以都有存get(),取set()方法,也都可以通過各自的靜態方法allocation,創建緩沖區。該方法是通過warpping將現有的數組包裝到緩沖區中來為緩沖區的內容分配空間,或者通過創建現有字節緩沖區的視圖來創建。
? ? ? 下面這是一個簡單的實例,從上到下,創建一個整型的緩沖區,然后將現有的數組放到該緩沖區中。可以通過put改變數組中的數據,并且由于緩沖區中的數據對數組是可見的,所以改變緩沖區也會改變數據,可以認為是傳引用。flip(),由于get()每調用一次,position位置都會改變,本來pos會等于3的,而用flip可以讓pos變為0;clear()效果也一樣。而duplicate()可以復制一個緩沖區,一模一樣,也是傳引用,修改哪個都會影響到另一個。
?
import java.nio.IntBuffer; import java.util.Arrays; public class BufferTest { public static void main(String[] args) { IntBuffer intBuffer = IntBuffer.allocate(10); int[] intArray = new int[]{3,5,7}; intBuffer = intBuffer.wrap(intArray); intBuffer.put(0,9); for(int i=0;i<intBuffer.limit();i++) { System.out.print(intBuffer.get()+"\t"); } System.out.println("\n緩沖區的數據對數組是可見的,修改視圖,數組中的數據也會變;傳引用"); Arrays.stream(intArray).forEach(temp-> System.out.print(temp+"\t")); intBuffer.clear(); System.out.println(intBuffer); IntBuffer intBuffer2 = intBuffer.duplicate(); System.out.println(intBuffer2); intBuffer2.put(0,11); for(int i=0;i<intBuffer.limit();i++) { System.out.print(intBuffer.get()+"\t"); } System.out.println("\n復制的緩沖區對原來的緩沖區也是可見的;傳引用"); for(int i=0;i<intBuffer2.limit();i++) { System.out.print(intBuffer2.get()+"\t"); } } } ? ? ? 結果是這樣
?
9 5 7
緩沖區的數據對數組是可見的,修改視圖,數組中的數據也會變;傳引用
9 5 7 java.nio.HeapIntBuffer[pos=0 lim=3 cap=3]
java.nio.HeapIntBuffer[pos=0 lim=3 cap=3]
11 5 7
復制的緩沖區對原來的緩沖區也是可見的;傳引用
11 5 7
? ? ? 未完待續!
轉載于:https://www.cnblogs.com/wsnb8/p/9255339.html
總結
以上是生活随笔為你收集整理的IO流与NIO流的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。