淺談JAVA中輸入輸出流實(shí)例詳解
java語言的輸入輸出功能是十分強(qiáng)大而靈活的,美中不足的是看上去輸入輸出的代碼并不是很簡潔,因?yàn)槟阃枰b許多不同的對象。在Java類庫中,IO部分的內(nèi)容是很龐大的,因?yàn)樗婕暗念I(lǐng)域很廣泛:標(biāo)準(zhǔn)輸入輸出,文件的操作,網(wǎng)絡(luò)上的數(shù)據(jù)流,字符串流,對象流,zip文件流....本文的目的是為大家介紹JAVA中輸入輸出流實(shí)例詳解。
流的層次結(jié)構(gòu)
定義:
java將讀取數(shù)據(jù)對象成為輸入流,能向其寫入的對象叫輸出流。結(jié)構(gòu)圖如下:
1、輸入輸出:
輸入/輸出(Input/Output)是指對某個(gè)設(shè)備或環(huán)境進(jìn)行數(shù)據(jù)的輸入或輸出.任何語言都有輸入輸出的功能,在Java程序中,是通過流來完成輸入和輸出的,它通過Java輸入輸出系統(tǒng)連接到物理設(shè)備,雖然輸入輸出流所連接的實(shí)際物理設(shè)備并不一樣,但卻可以以同一種方式工作.例如對硬盤的輸入輸出,對網(wǎng)絡(luò)主機(jī)進(jìn)行輸入輸出,因此設(shè)備或者環(huán)境的不同會有各式各樣的輸入輸出的問題與解決方案.
2、流:
流是指在計(jì)算機(jī)的輸入與輸出之間運(yùn)動的數(shù)據(jù)序列.流序列中的數(shù)據(jù)既可以是未經(jīng)加工的原始的二進(jìn)制數(shù)據(jù),也可以是經(jīng)一定編碼處理后符合某種格式規(guī)定的特定數(shù)據(jù).習(xí)慣上稱代碼相關(guān)的部分為內(nèi)部,稱與代碼無關(guān)的部分為外部.
從數(shù)據(jù)的傳輸方式劃分,流可分為輸入流和輸出流;從流的內(nèi)容上劃分,流可分為字節(jié)流和字符流.
(1) 輸入輸出流
輸入流的作用是從程序內(nèi)部向外部讀取數(shù)據(jù).
輸出流的作用是從程序外部向內(nèi)部寫入數(shù)據(jù).
(2) 字節(jié)流和字符流
字流(byte stream)對數(shù)據(jù)以字節(jié)為單位進(jìn)行讀寫,既可以一個(gè)字節(jié)接一個(gè)字節(jié)的讀寫數(shù)據(jù),也可以一次讀寫任意長度的字節(jié)塊(即字節(jié)數(shù)組).
字符流(character stream)在讀寫流內(nèi)數(shù)據(jù)時(shí)是以字符為單位,一次一個(gè)字符,或者一次一個(gè)字符塊.
為了方便流的處理,Java語言的流都封裝在java.io包中,所以要使用流,必須導(dǎo)入java.io包.
Java的I/O流是建立在四個(gè)抽象類的基礎(chǔ)上,分別是InputStream, OutputStream, Reader和Writer.InputStream類及其子類可用于實(shí)現(xiàn)字節(jié)流數(shù)據(jù)的輸入處理;OutputStream類及其子類可用于實(shí)現(xiàn)字節(jié)流數(shù)據(jù)的輸出處理;Reader類及其子類可用于實(shí)現(xiàn)字符流數(shù)據(jù)的輸入處理;Writer類及其子類可用于實(shí)現(xiàn)字符流數(shù)據(jù)的輸出處理.
一、File類
Java中對文件的讀寫操作可以通過輸入輸出流來實(shí)現(xiàn),但對于文件目錄、屬性以及管理等信息Java提供了一個(gè)專門的File類來實(shí)現(xiàn).
(1) File類的構(gòu)造方法
創(chuàng)建一個(gè)File類對象的構(gòu)造方法有:
File (String pathname); //根據(jù)路徑名創(chuàng)建.
File (File parent, String child); //在給定File對象下創(chuàng)建.
File (String parent, String child); //根據(jù)指定路徑下創(chuàng)建.
File (URL url); //根據(jù)一個(gè)URL鏈接創(chuàng)建.
(2) File類的常用方法
boolean canRead():判斷File對象對應(yīng)的路徑是否可讀.
boolean canWrite():判斷File對象對應(yīng)的路徑是否可寫.
boolean exists():判斷File對象對應(yīng)的路徑是否存在.
String getAbsolutePath():獲取File對象對應(yīng)路徑的絕對路徑.
String getParent():獲取File對象對應(yīng)路徑的目錄.
String getPath():獲取File對象對應(yīng)的路徑.
boolean isAbsolute():判斷File對象對應(yīng)的路徑是否為絕對路徑.
String getName():獲取File對象對應(yīng)路徑的文件名.
boolean isDirectory():判斷File對象對應(yīng)的路徑是否為目錄.
boolean isFile():判斷File對象對應(yīng)的路徑是否為文件.
boolean isHidden():判斷File對象對應(yīng)的文件是否為隱藏屬性.
long length():獲得File對象對應(yīng)文件的長度.
long lastModified():獲得File對象對應(yīng)文件的最近修改時(shí)間.
boolean renameTo(File dest):更改File對象對應(yīng)文件的文件名.
boolean setReadOnly():設(shè)置File對象對應(yīng)文件為只讀.
(3) 創(chuàng)建文件
通過創(chuàng)建一個(gè)文件輸出流來創(chuàng)建一個(gè)新文件.這種方式不能創(chuàng)建目錄,并且如果要?jiǎng)?chuàng)建的文件已存在,會新建一個(gè)文件覆蓋原文件.
FileOutrputStream file = new FileOutputStream(“filename”);
(4) 獲得文件列表
通過File類的list()或listFiles()方法獲得某個(gè)文件夾的文件列表.有以下幾種形式:
String[] list();
File[] listFiles();
File[] listFiles(FilenameFilter filter);
File[] listFiles(FileFilter filter);
其中,F(xiàn)ileFilter和FilenameFilter都是接口,filter為相應(yīng)的過濾器.聲明某個(gè)類,實(shí)現(xiàn)過濾器接口,便可以通過過濾條件來列出所有符合的文件.
二、InputStream類和OutputStream類
字節(jié)流類是從抽象類InputStream和OutputStream派生出來的一系列類.這類流以字節(jié)為基本處理單位.InputStream 和 OutputStream類除了可以用來處理二進(jìn)制文件的數(shù)據(jù)之外,也可以用來處理文本文件.
1、InputStream類的常用方法
InputStream類是所有輸入流的父類,該類的所有方法在錯(cuò)誤發(fā)生時(shí)都會拋出IOException,主要的方法有:
(1) public abstract int read() thows IOException
方法返回一個(gè)0至255之間的整數(shù)或-1, -1代表遇到了流的結(jié)束,其它對應(yīng)讀入的字節(jié).
(2) public int read(byte[]b) thows IOException
方法將字節(jié)讀入?yún)?shù)給定的字節(jié)數(shù)組,返回值是實(shí)際讀入的字節(jié)數(shù)或-1(遇到了流結(jié)束).
(3) public int read(byte[]b, int i, int b) thows IOException
方法的后兩個(gè)參數(shù)分別給出讀入的起始位置和讀入的最大字節(jié)數(shù).
(4) public int available()
返回當(dāng)前流對象中還沒有被讀取的字節(jié)數(shù)量.也就是獲得流中數(shù)據(jù)的長度.
(5) public long skip(long n)
跳過當(dāng)前流對象中的n個(gè)字節(jié),而實(shí)際跳過的字節(jié)數(shù)量則以返回值的方式返回.
(6) public boolean markSupported()
判斷流是否支持標(biāo)記(mark),標(biāo)記可以方便的回到原來讀過的位置.
(7) public void close()
關(guān)閉當(dāng)前流對象,并釋放該流對象占用的資源.
(8) public void mark(int i)
為流中當(dāng)前的位置設(shè)置標(biāo)志,使得以后可以從該位置繼續(xù)讀取.
(9) public void reset()
使流讀取的位置回到設(shè)定標(biāo)記的位置.
2、OutputStream類的常用方法
OutputStream類是所有輸出流的父類,該類所有方法都返回void,并且在錯(cuò)誤情況下拋出IOException,主要的方法有:
(1) public void write(int b) throws IOException
向流的末尾寫入一個(gè)字節(jié)的數(shù)據(jù).
(2) public void write(byte[] b) throws IOException
將數(shù)組b中的數(shù)據(jù)依次寫入當(dāng)前的流對象中.
(3) public void wirte(byte[]b, int i, int n)
將數(shù)組中從開始下標(biāo)(包含),后續(xù)長度的數(shù)據(jù)依次寫入到流對象中.
(4) public void close()
關(guān)閉當(dāng)前流對象,并釋放該流對象占用的資源.
(5) public void flush()
將當(dāng)前流對象中的緩沖數(shù)據(jù)強(qiáng)制輸出出去.使用該方法可以實(shí)現(xiàn)立即輸出.
上面兩個(gè)類的大多數(shù)方法由InputStream和OutputStream的子類覆蓋,mark()和reset()方法除外.
3、FileInputStream類
FileInputStream類是InputStream的子類,可以用來處理以文件作為數(shù)據(jù)輸入源的數(shù)據(jù)流,實(shí)現(xiàn)文件的讀取操作.
它的構(gòu)造方法有:
(1) FileInputStream(File f)
以指定名字的文件對象f為數(shù)據(jù)源建立文件輸入流.
如果f存在的話但是它應(yīng)是一個(gè)文件路徑,如果是目錄則會拋出IOException,但是如果是這個(gè)目錄不存在的時(shí)候則會拋出:FileNotFoundException.
(2) FileInputStream(String name)
以名為name的文件為數(shù)據(jù)源建立文件輸入流.
(3) FileInputStream(FileDescriptor f)
根據(jù)文件描述符對象f為輸入端建立一個(gè)文件輸入流.
它的主要方法是覆蓋了父類(InputStream類)的方法:read()、read(byte[]b)、read(byte[]b , int i, int length)、skip(long n)、available()、close().
4、FileOutputStream類
FileOutputStream類是OutputStream的子類,用來處理以文件作為數(shù)據(jù)輸出的數(shù)據(jù)流,實(shí)現(xiàn)對文件的寫入操作.它的構(gòu)造方法有:
FileOutputStream(File f);
FileOutputStream(File f, boolean b);
FileOutputStream(String f);
它的主要的方法有覆蓋父類的方法:write(int b)、write(byte[]b)、write(byte[]b,int off,int len)、close()、flush().
5、DataInputStream和DataOutputStream類
DateInputStream和DataOutputStream類創(chuàng)建的對象分別被稱為數(shù)據(jù)輸入流和數(shù)據(jù)輸出流.它們分別實(shí)現(xiàn)了DataInput接口和DataOutput接口.DateInputStream類和DataOutputStream對象允許讀取Java各種類型的數(shù)據(jù).
這兩個(gè)流屬于過濾流,常以其它流如InputStream或OutputStream作為它們的輸入或輸出.例如:
FileInputStream fis = new FileInputStream("d:\\a.txt");
DataInputStream dis = new DataInputStream(fis);
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
DataOutputStream dos = new DataOutputStream(fos);
DateInputStream和DataOutputStream的輸入和輸出幾乎是對應(yīng)的,每種基本數(shù)據(jù)類型的讀寫方法可以從其后綴名字識別.例如:
readInt(),writeInt() // 讀寫一個(gè)int值
readBoolean(),writeBoolean() // 讀寫一個(gè)布爾值
readChar(),writeChar() // 讀寫一個(gè)字符
readDouble(),writeDouble() // 讀寫一個(gè)雙精度浮點(diǎn)值
readFloat(),writeFloat() // 讀寫一個(gè)單精度浮點(diǎn)值
WriteChars() // 寫一個(gè)字符串,但沒有直接讀字符串的方法
三、Reader類和Writer類
Java中的字符使用的是Unicode編碼,每個(gè)字符占有兩個(gè)字節(jié),即16bit.字符流是以16位的Unicode碼表示的字符為基本處理單位,進(jìn)行文本數(shù)據(jù)的讀寫,可以實(shí)現(xiàn)Java程序中的內(nèi)部格式和文本文件、顯示輸出、鍵盤輸入等外部格式之間的轉(zhuǎn)換.這種方法尤其適合漢字的操作.如果漢字以字節(jié)形式操作,有可能輸出亂碼.
Reader和Writer是java.io包中所有字符流的抽象父類,定義了實(shí)現(xiàn)其他流類的關(guān)鍵方法.其中兩個(gè)最重要的是read()和write(),它們分別進(jìn)行字符數(shù)據(jù)的讀和寫.Reader及Writer類和它們子類的方法,與InputStream類和OutputStream類及它們子類的使用方法非常類似.只不過其中的參數(shù)換成字符或字符數(shù)組.
1、Reader類和Writer類的常用方法
Reader類是個(gè)抽象類,該類的所有方法在錯(cuò)誤條件下都會拋出IOException異常.常用方法如下:
(1) abstract void close():關(guān)閉輸入源.
(2) void mark(int numChars):放置一個(gè)標(biāo)記到輸入源的當(dāng)前點(diǎn).
(3) boolean markSupported():如果這個(gè)流支持mark/reset方法,將返回true.
(4) int read():讀取單個(gè)字符.
(5) int read(char[] buf):讀字符讀入到字符數(shù)組.
(6) abstract int read(char[] buf, int offset, int numChars): 將字符讀入數(shù)組的某一部分.
(7) boolean ready():如果下一個(gè)輸入請求不必等待,返回true,否則返回false.
(8) void reset():重置輸入指針到前面設(shè)置的標(biāo)記.
(9) long skip(long numChars):跳過n個(gè)字符輸入,返回實(shí)際跳過的字符數(shù).
Writer類也是個(gè)抽象類,常用方法如下:
(1) abstract void close():關(guān)閉輸出流.
(2) abstract void flush():確定輸出狀態(tài)以便清空任何緩存.
(3) void write(int ch):寫入單個(gè)字符.
(4) void write(char[] buf):寫入字符數(shù)組.
(5) abstract void write(char[] buf, int offset, int numChars):寫入字符數(shù)組的一部分.
(6) void write(String str):寫入字符串.
(7) void write(String str, int offset, int numChars):寫入字符串的一部分.
2、FileReader類
FileReader類是繼承自InputStreamReader類,而InputStreamReader類又繼承自Reader類,因此Reader類與InputStreamReader類所提供的方法均可供FileReader類所創(chuàng)建對象使用.FileReader的構(gòu)造方法有:
FileReader(File file);
FileReader(FileDescriptor e );
FileReader(String filename);
3、FileWriter類
FileWriter類繼承自O(shè)utputStreamWriter類,而OutputStreamWriter類又繼承自Writer類,因此Writer類與OutputStreamWriter類所提供的方法均可供FileWriter類所創(chuàng)建對象使用.FileWriter的構(gòu)造方法有:
FileWrite(File filePath);
FileWrite(File f, boolean append);
FileWrite(FileDescriptor e);
FileWrite(String filename);
FileWrite(String filename,boolean append);
4、BufferedReader類
BufferedReader類繼承自Reader類,BufferedReader類是用來讀取緩沖區(qū)里的數(shù)據(jù).BufferedReader類屬于過濾流,常以其它流如FileReader作為它們的輸入或輸出.它的構(gòu)造方法有:
BufferedReader(Reader in);
BufferedReader(Reader in, int bufSize);
例如:
FileReader fr=new FileReader("d:\1.txt");
BufferedReader buf = new BufferedReader(fr);
BufferedReader提供了readerLine()方法用來讀取文本每一行.
5、BufferedWriter類
BufferedWriter類繼承自Writer類,BufferedWriter類是用來將數(shù)據(jù)寫入到緩沖區(qū)里.使用BufferedWriter類與使用BufferedReader類過程相似.不同的是,緩沖區(qū)內(nèi)的數(shù)據(jù)最后必須要用flush()方法將緩沖區(qū)清空,也就是將緩沖區(qū)中的數(shù)據(jù)全部寫到文件內(nèi).它的構(gòu)造方法有:
BufferedWriter(Writer out);
BufferedWriter(Writer out, int bufSize);
四、RandomAccessFile類
Java中的隨機(jī)文件訪問需要用到RandomAccessFile類(該類允許從任意位置訪問,不僅能讀取,而且能寫入),它直接從Object類繼承,并實(shí)現(xiàn)接口DataInput和DataOutput.
由于RandomAccessFile類實(shí)現(xiàn)了DataInput和DataOutput接口中所定義的所有方法,能夠從文件中讀取基本類型的數(shù)據(jù),也能向文件寫入基本類型的數(shù)據(jù).除了DataInput和DataOutput接口中定義的方法以外,RandomAccessFile類還定義了其他的一些方法來支持隨機(jī)訪問.
RandomAccessFile類創(chuàng)建的流與前面的輸入、輸出流不同,RandomAccessFile類既不是輸入流類InputStream類的子類,也不是輸出流類OutputStram類的子類流.但是RandomAccessFile類創(chuàng)建的流的指向既可以作為源也可以作為目的地,換句話說,當(dāng)對一個(gè)文件進(jìn)行讀寫操作時(shí),可以創(chuàng)建一個(gè)指向該文件的RandomAccessFile流即可,這樣既可以從這個(gè)流中讀取這個(gè)文件的數(shù)據(jù),也通過這個(gè)流寫入數(shù)據(jù)給這個(gè)文件.
RandomAccessFile類的兩個(gè)構(gòu)造方法:
(1) RandomAccessFile(String name, String mode)
參數(shù)name 用來確定一個(gè)文件名,給出創(chuàng)建的流的源(也是流目的地),參數(shù)mode取r(只讀)或rw(可讀寫),決定創(chuàng)建的流對文件的訪問權(quán)利.
(2) RandomAccessFile(File file, String mode)
參數(shù)file 是一個(gè)File對象,給出創(chuàng)建的流的源(也是流目的地),參數(shù)mode取r(只讀)或rw(可讀寫),決定創(chuàng)建的流對文件的訪問權(quán)利.創(chuàng)建對象時(shí)應(yīng)捕獲FileNotFoundException異常;當(dāng)流進(jìn)行讀寫操作時(shí),應(yīng)捕獲IOException異常.
對象RandomAccessFile讀寫信息的方法同數(shù)據(jù)輸入輸出對象的方法相同,它可以訪問類DataInputStream和DataOutputStream中的所有read()、write()方法.
移動文件讀寫指針的方法:
(1) long getFilePointer():返回文件指針的當(dāng)前位置.
(2) void seek(long pos):將文件指針置于指定的絕對位置.位置值以從文件開始處的字節(jié)偏移量pos來計(jì)算,pos為0代表文件的開始.
(3) long length():返回文件的長度.位置值為length(),代表文件的結(jié)尾.
相關(guān)文章
Java concurrency之AtomicReference原子類_動力節(jié)點(diǎn)Java學(xué)院整理
AtomicReference是作用是對"對象"進(jìn)行原子操作。這篇文章主要介紹了Java concurrency之AtomicReference原子類,需要的朋友可以參考下2017-06-06Java日期時(shí)間處理問題(從Date、Calendar到SimpleDateFormat)
這篇文章主要介紹了Java日期時(shí)間處理深度解析(從Date、Calendar到SimpleDateFormat),我們詳細(xì)討論了Java中的日期和時(shí)間處理,包括Date、Calendar和SimpleDateFormat類的使用,以及Java?8引入的新的日期時(shí)間API的優(yōu)勢,需要的朋友可以參考下2024-08-08SpringBoot + FFmpeg實(shí)現(xiàn)一個(gè)簡單的M3U8切片轉(zhuǎn)碼系統(tǒng)
使用大名鼎鼎的ffmpeg,把視頻文件切片成m3u8,并且通過springboot,可以實(shí)現(xiàn)在線的點(diǎn)播。2021-05-05SpringBoot中的ApplicationRunner與CommandLineRunner問題
這篇文章主要介紹了SpringBoot中的ApplicationRunner與CommandLineRunner問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09SpringBoot實(shí)現(xiàn)接口等冪次校驗(yàn)的示例代碼
本文主要介紹了SpringBoot實(shí)現(xiàn)接口等冪次校驗(yàn)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Java實(shí)現(xiàn)ATM機(jī)操作系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)ATM機(jī)操作系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05