2019獨角獸企業重金招聘Python工程師標準>>>
IO 流有很多種,按照操作數據的不同,可以分為字節流和字符流,按照數組傳輸方向的不同又可分為輸入流和輸出流。字節流的輸入輸出流分別用 java.io.InputStream 和 java.io.OutputStream表示,字符流的輸入輸出流分別用 java.io.Reader 和 java.io.Writer 表示。
一、字節流
1、字節流的概念
?? 在計算機中,無論文本、圖片、音頻還是視頻,所有的文件都是以二進制(字節)的形式存在,IO 流中針對自己的輸入和輸出提供了一系列的流,統稱為字節流。
?? 字節流是程序中最常用的流,根據數據的傳輸方向可將其分為字節輸入流和字節輸出流,在 JDK 中提供了兩個抽象類 InputStreanm 和 OutputStream ,他們是字節流的頂級父類,所有的字節輸入流都繼承自 InputStream,所有的字節輸出流都是繼承自 OutputStream。
?? InputStream 的常用方法:
???OutputStream 的常用方法:
?? InputStream 和 OutputStream 這兩個類雖然提供了一系列和讀寫數據有關的方法,但是這兩個類是抽象類,不能被實例化,因此針對不同的功能,InputStream 和 OutputStream 提供了不同的子類。
2、字節流讀取文件
?? 針對文件的讀寫,JDK 專門提供了兩個類,分別是 FileInputStream 和 FileInputStream。FileInputStream 是 InputStream 的子類,它是操作文件的字節輸入流,專門用于讀取文件中的數據。
?
[java]?view plain?copy
import?java.io.*;??class?StreamDemo1{??????public?static?void?main(String[]?args)throws?Exception{??????????FileInputStream?in?=?new?FileInputStream("test.txt");??????????int?b?=?0;??????????while(true){??????????????b?=?in.read();??????????????if(b?==?-1){??????????????????break;??????????????}??????????????System.out.println(b);??????????}??????????in.close();??????}??}???
?? 需要注意的是,在讀取文件數據時,必須保證文件是存在并且可讀的,否則會拋出文件找不到異常 FileNotFoundException。
?? 與 FileInputStream 對應的是 FileOutputStream ,它是操作文件的字節輸出流,專門用于把數據寫入文件。
?
[java]?view plain?copy
import?java.io.*;??class?StreamDemo2{??????public?static?void?main(String[]?args)throws?Exception{??????????FileOutputStream?out?=?new?FileOutputStream("test.txt");??????????String?str?=?"傳智播客";??????????byte[]?b?=?str.getBytes();??????????for(int?x=0;x<b.length;x++){??????????????out.write(b[x]);??????????}??????????out.close();??????}??}???
?? 需要注意的是,如果是通過 FileOutputStream 向一個已經存在的文件中寫入數據,那么該文件中的數據首先被清空,再寫入新的數據。如果希望在已存在的文件內容之后追加新內容,則可以使用 FileOutputStream 的構造函數 FileOutputStream(String fileName,boolean append) 來創建文件輸出流對象,并把 append 參數的值設置為 true。
?
[java]?view plain?copy
import?java.io.*;??class?StreamDemo3{??????public?static?void?main(String[]?args)throws?Exception{??????????FileOutputStream?out?=?new?FileOutputStream("test.txt",true);??????????String?str?=?"歡迎你";??????????byte[]?b?=?str.getBytes();??????????for(int?x=0;x<b.length;x++){??????????????out.write(b[x]);??????????}??????????out.close();??????}??}???
?? 為了保證 IO 流的 close() 方法將無法得到執行,流對象所占用的系統資源將得不到釋放,因此為了保證 IO 流的 close() 方法必須執行,通常將關閉流的操作寫在 finally 代碼塊中。
?
[java]?view plain?copy
FileInputStream?in?=?null;??FileOutputStream?out?=?null;??try{??????in?=?new?FileInputStream("test.txt");??????out?=?new?FileOutputStream("copy.txt");??}catch(Exception?e){??????throw?new?RuntimeException("讀寫失敗");??}finally{??????try{??????????if(in?!=?null)??????????????in.close();??????}catch(Exception?e){??????????e.printStackTrace();??????}??????try{??????????if(out?!=?null)??????????????out.close();??????}catch(Exception?e){??????????e.printStackTrace();??????}??}?? 3、文件拷貝
[java]?view plain?copy
class?StreamDemo4{??????public?static?void?main(String[]?args){??????????//創建一個字節輸入流,讀取c盤下的mp3文件??????????InputStream?in?=?new?FileInputStream("c:\\新不了情.mp3");??????????//創建一個字節輸出流,將讀取的數據寫入到d盤中??????????OutputStream?out?=?new?FileOutputStream("d:\\xinbuliaoqing.mp3");??????????int?len;??????????while((len=in.read())!=-1){??????????????out.write(len);??????????}??????????in.close();??????????out.close();??????}??}???? 當通過流的方式拷貝文件時,為了提高效率可以定義一個字節數組作為緩沖區,一次性讀取多個字節的數據,并保存在字節數組中,然后將字節數組中的數據一次性寫入文件。
?
[java]?view plain?copy
class?StreamDemo4{??????public?static?void?main(String[]?args){??????????//創建一個字節輸入流,讀取c盤下的mp3文件??????????InputStream?in?=?new?FileInputStream("c:\\新不了情.mp3");??????????//創建一個字節輸出流,將讀取的數據寫入到d盤中??????????OutputStream?out?=?new?FileOutputStream("d:\\xinbuliaoqing.mp3");??????????byte[]?buff?=?new?byte[1024];??????????int?len;??????????while((len=in.read(buff))!=-1){??????????????out.write(buff,0,len);??????????}??????????in.close();??????????out.close();??????}??}???
4、裝飾者模式
?? 裝飾者模式就是通過包裝一個類,動態地為它增加一種設計模式。
?
[java]?view plain?copy
//比如買了一輛車,香味新車裝一個倒車雷達,這就相當于為這輛汽車增加了新的功能。??class?Car{??????private?String?carName;??????public?Car(String?carName){??????????this.carName?=?carName;??????}??????public?void?show(){??????????System.out.println("我是"+carName+",具備基本功能。");??????}??}??class?RadarCar{??????public??Car?myCar;??????public?RadarCar(Car?myCar){??????????this.myCar?=?myCar;??????}??????public?void?show(){??????????myCar.show();??????????System.out.println("具備雷達功能");??????}??}???
5、字節流緩沖區
?? 在 IO 包中提供了兩個帶緩沖區的字節流,他們分別是 BufferedInputStream 和 BufferedOutputStream ,這兩個流使用了裝飾者設計模式。他們的構造方法分別接受 InputStream 和 OutputStream 類型的參數作為被包裝的對象,在讀寫數據時提供緩沖功能。
?
[java]?view plain?copy
class?StreamDemo5{??????public?static?void?main(String[]?args){??????????BufferedInputStream?buffin?=?new?BufferedInputStream(new?FileInputStream("src.txt"));??????????BufferedOutputStream?buffout?=?new?BufferedOutputStream(new?FileOutputStream("dex.txt"));??????????int?len;??????????while((len=buffin.read())!=-1){??????????????buffout.write(len);??????????}??????????buffin.close();??????????buffout.close();??????}??}???
二、字符流
1、字符流簡介
??? 字符流也有兩個抽象的頂級父類 Reader 和 Writer,其中 Reader 是字符輸入流,用于從某個原設備中讀取字符,Writer 是字符輸出流,用于向某個目標設備寫入字符。
2、字節流操作文件
?? 經常需要對文本文件的內容進行讀取,如果從文件中直接讀取字符便可以使用輸入流FileReader ,通過此流可以從關聯的文件周總讀取一個或一組字符。
?
[java]?view plain?copy
//使用FileReader讀取reader.txt文件中的內容??class?ReaderDemo{??????public?static?void?main(String[]?args){??????????FileReader?reader?=?new?FileReader("reader.txt");??????????int?ch;??????????while((ch=reader.read())!=-1){??????????????System.out.println((char)ch);??????????}??????????reader.close();??????}??}???
?? FileWriter 同 FileOutputStream 一樣,如果指定的文件不存在,就會先創建文件,再寫入數據,如果文件存在,則會首先清空文件中的內容榮,再進行寫入。如果想要在我呢間末尾追加數據,同樣需要調用重載的構造方法。
?
[java]?view plain?copy
//使用FileWriter將字符串寫入到writer.txt文件??class?WriterDemo{??????public?static?void?main(String[]?args){??????????FileWriter?writer?=?new?FileWriter("writer.txt");??????????String?str?=?"傳智播客";??????????writer.write(str);??????????writer.close();??????}??}???
?? 字符流同樣提供了帶緩沖區的包裝流,分別是 BufferedReader 和 BufferedWriter,需要注意的是,在 BufferedReader 中有一個重要的方法 readeLine() ,該方法用于一次讀取一行文本。
?
[java]?view plain?copy
class?BufferedReaderDemo{??????public?static?void?main(String[]?args){??????????BufferedReader?buffin?=?new?BufferedReader(new?FileReader("src.txt"));??????????BufferedWriter?buffout?=?new?BufferedWriter(new?FileWriter("des.txt"));??????????String?str;??????????while((str=buffin.read())!=null){??????????????buffout.write(str);??????????????buffout.newLine();??????????}??????????buufin.close();??????????buffer.close();??????}??}???
3、LineNumberReader
?? Java 程序在編譯或運行時期經常會出現一些錯誤,在錯誤中通常會報告出錯的行號,為了方便查找錯誤,需要在代碼中加入行號。
?
[java]?view plain?copy
class?LineNumberReaderDemo{??????public?static?void?main(String[]?args){??????????FileReader?fr?=?new?FileReader("src.txt");??????????FileWriter?fw?=?new?FileWriter("dex.txt");??????????LineNumberReader?lr?=?new?LineNumberReader(fr);??????????lr.setLineNumber(0);??????????String?line?=?null;??????????while((line=lr.readLine())!=null){??????????????fw.write(lr.getLineNumber()+":"+line);??????????}??????????lr.close();??????????fw.close();??????}??}???
4、轉換流
?? 有時候字節流和字符流之間也需要進行轉換,在 JDK 中提供了兩個類可以將字節流轉換為字符流,它們分別是 InputStreamReader 和 OutputStreamWriter。
?? 轉換流也是一種包裝流。
?
[java]?view plain?copy
class?InputStreamReaderDemo{??????public?static?void?main(String[]?args){??????????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(new?FileInputStream("src.txt")));??????????BufferedWriter?bw?=?new?BufferedWriter(new?OutputStreamWriter(new?FileInputStream("dex.txt")));??????????String?line;??????????while((line=br.readLine())!=null){??????????????bw.write(line);??????????}??????????br.close();??????????bw.close();??????}??}???
?
三、其他 IO 流
1、ObjectInputStream 和 ObjectOutputStream
?? 程序運行時會在內存中創建多個對象,然后程序結束后,這些對象便被當做垃圾回收了。如果希望永久保存這些對象,則可以將對象轉為字節數組寫入到硬盤中,這個過程被稱為對象序列化。
?? JDK 提供了 ObjectOutputStream(對象輸出流)來實現對象的實例化,當對象進行實例化時,必須保證該對象是想 Serializable 接口,否則程序會出現 NotSerializableException 異常。
?
[java]?view plain?copy
class?ObjectOutputStreamDemo{??????public?static?void?main(String[]?args){??????????Person?p?=?new?Person("0001","zhangsan",26);??????????FileOutputStream?fos?=?new?FileOutputStream("object.txt");??????????ObjectOutputStream?oos?=?new?ObjectOutputStream(fos);??????????oos.writeObject(p);??????}??}??class?Person?implements?Serializable{??????private?String?id;??????private?String?name;??????private?int?age;??????public?Person(String?id,String?name,int?age){??????????this.id?=?id;??????????this.name?=?name;??????????this.age?=?age;??????}??????public?String?getId(){??????????return?id;??????}??????public?String?getName(){??????????return?name;??????}??????public?int?getAge(){??????????return?age;??????}??}???
?? Person 對象被序列化后會生成二進制數據保存在“object.txt”文件中,通過這些二進制數據可以恢復序列化之前的 Java 對象,此過程稱為反序列化。
?? JDK 提供了 ObjectInputStream(對象輸入流),它可以實現對象的反序列化。
?
[java]?view plain?copy
class?ObjectInputStreamDemo{??????public?static?void?main(String[]?args){??????????FileInputStream?fis?=?new?FileInputStream("object.txt");??????????ObjectOutputStream?ois?=?new?ObjectOutputStream(fis);??????????Person?p?=?(Person)ois.readObject();??????????System.out.println(p.getId()+","+p.getName()+","+p.getAge());??????}??}??class?Person?implements?Serializable{??????private?String?id;??????private?String?name;??????private?int?age;??????public?Person(String?id,String?name,int?age){??????????this.id?=?id;??????????this.name?=?name;??????????this.age?=?age;??????}??????public?String?getId(){??????????return?id;??????}??????public?String?getName(){??????????return?name;??????}??????public?int?getAge(){??????????return?age;??????}??}???
2、DataInputStream 和 DataOutputStream
?? 有的時候并不需要存儲整個對象的信息,而只需要存儲對象的成員數據,這些成員數據的類型又都是基本數據類型,這時不必使用對象 Object 相關的流,可以使用 IO 包中提供的另外兩個操作流:DataInputStream 和 DataOuputStream。
?? DataInputStream 和 DataOutputStream 是兩個與平臺無關的數據操作流,他們不僅提供了讀寫各種基本類型數據的方法,而且還提供了 readUTF() 和 writeUTF() 方法,DatinputStream 的 readUTF() 方法能夠從輸入流中讀取采用 UTF-8 字符編碼的字符串,DataOutputStream 的 writeUTF() 方法則可向輸出流中寫入采用 UTF-8 字符編碼的字符串。
?
[java]?view plain?copy
class?DataInputStreamDemo{??????public?static?void?main(String[]?args){??????????BufferedOutputStream?bos?=?new?BufferedInputStream(new?FileOutputStream("d:\data.txt"));??????????DataOutputStream?dos?=?new?DataOutputStream(bos);??????????dos.writeByte(12);??????????dos.writeChar("1");??????????dos.writeBoolean(true);??????????dos.writeUTF("你好");??????????dos.close();????????????BufferedInputStream?bis?=?new?BufferedInputStream(new?FileInputStream("d:\data.txt"));??????????DataInputStream?dis?=?new?DataInputStream(bis);??????????System.out.println(dis.readByte());??????????System.out.println(dis.readChar());??????????System.out.println(dis.readBoolean());??????????System.out.println(dis.readUTF());??????????dis.close();??????}??}???
?? 需要注意的是,只有讀取數據的順序與寫入的順序保持一致,才能保證最終數據的正確性。
3、PrintStream
?? PrintStream 提供了一系列用于打印數據的 print() 和 println() 方法,被稱作打印流,可以實現將基本數據類型或引用數據類型的對象格式化成字符串后再輸出。
?
[java]?view plain?copy
class?PrintStreamDemo{??????public?static?void?main(String[]?args){??????????PrintStream?ps?=?new?PrintStream(new?FileOutputStream("print.txt"),true);??????????Student?sru?=?new?Student();??????????ps.print("這是一個數字:");??????????ps.println(19);??????????ps.println(stu);??????}??}??class?Studnet{??????public?String?toString(){??????????return?"我是一個學生";??????}??}???
4、標準輸入輸出流
?? 在 System 類中定義了三個常量:in、out 和 err,它們被習慣性地稱為標準輸入輸出流。其中,in 為 InputStream 類型,它是標準輸入流,默認情況下用于讀取鍵盤輸入的數據;out 為 PrintStream 類型,它是標準輸出流,默認將數據輸出到命令行窗口;err 也是 PrintStream 類型,它是標準錯誤流,它和 out 一樣也是將數據輸出到控制臺,不同的是 err 通常輸出的是應用程序運行時的錯誤信息。
?
[java]?view plain?copy
class?InOutDemo{??????public?static?void?main(String[]?args){??????????StringBuffer?sb?=?new?StringBuffer();??????????int?ch;??????????while((ch=System.in.read())!=-1){??????????????if(ch=="\r"?||?ch=="\n")??????????????????break;??????????????sb.append((char)ch);??????????}??????????System.out.println(sb);??????}??}???
?? 由于程序向命令行窗口輸出大量的數據,,可以將標準輸出流重新定向到其他的輸出設備。
?
[java]?view plain?copy
class?SetInOutDemo{??????public?static?void?main(String[]?args){??????????System.setIn(new?FileInputStream("src.txt"));??????????System.setOut(new?FileOutputStream("dex.txt"));??????????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(System.in));??????????String?line;??????????while((line=br.readLine())!=null){??????????????System.out.println(line);??????????}??????}??}???
5、PipedInputStream 和 PipedOutputStream
?? 多個線程之間也可以通過 IO 流實現數據的傳輸,為此 JDK 提供了一種管道流,管道流分為管道輸入流(PipedInputStream)和管道輸出流(PipedOutputStream),它是一種比較特殊的流,必須先建立連接才能進行彼此間通信。
?
[java]?view plain?copy
class?PipedStreamDemo{??????public?static?void?main(String[]?args)throws?Exception{??????????final?PipedInputStream?pis?=?new?PipedInputStream();??????????final?PipedOutputStream?pos?=?new?PipedOutputStream();??????????pis.connect(pos);????????????new?Thread(new?Runnable(){??????????????????public?void?run(){??????????????????????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(System.in));??????????????????????PrintStream?ps?=?new?PrintStream(pos);??????????????????????while(true){??????????????????????????try{??????????????????????????????System.out.print(Thread.currentThread().getName()+"要輸入的內容:");??????????????????????????????ps.println(br.readLine());??????????????????????????????Thread.sleep(1000);??????????????????????????}catch(Exception?e){??????????????????????????????e.printStackTrace();??????????????????????????}??????????????????????}??????????????????}??????????????},"發送數據的線程").start();??????????new?Thread(new?Runnable(){??????????????????public?void?run(){??????????????????????BufferedReader?br?=?new?BufferedReader(new?InputStream(pis));??????????????????????while(true){??????????????????????????try{??????????????????????????????System.out.print(Thread.currentThread().getName()+"收到的內容:");??????????????????????????}catch(Exception?e){??????????????????????????????e.printStackTrace();??????????????????????????}??????????????????????}??????????????????}??????????????},"接收數據的線程").start();??????}??}???
6、ByteArrayInputStream 和 ByteArrayOutputStream
?? 為了將文件臨時存儲到緩沖區,方便以后讀取,ByteArrayOuputStream 類會在創建對象時就創建一個 byte 型數組的緩沖區,當想數組中寫數據時,該對象會把所有的數據線寫入緩沖區,最后一次性寫入文件。
?
[java]?view plain?copy
class?ByteOutputStreamStreamDemo{??????public?static?void?main(String[]?args){??????????FileInputStream?fis?=?new?FileInputStream("src.txt");??????????ByteArrayOutputStream?bos?=?new?ByteArrayOutputStream();??????????FileOutputStream?fos?=?new?FileOutputStream("target.txt");??????????int?b;??????????while((b=fis.read())!=-1){??????????????bos.write(b);??????????}??????????in.xlose();??????????bos.close();??????????fos.write(bos.toByteArray());??????????fos.close();??????}??}???
?? 需要注意的是,如果讀取的文件非常大,就不能使用這個類,否則會造成內存溢出。
?? 與 ByteArrayOutputStream 類似,ByteArrayInputStream 是從緩沖區讀取數據。
?
[java]?view plain?copy
class?ByteInputStreamStreamDemo{??????public?static?void?main(String[]?args){??????????byte[]?buff?=?new?byte[]{97,98,99,100};??????????ByteArrayInputStream?bis?=?new?ByteArrayInputStream(buff);??????????int?b;??????????while((b=bis.read())!=-1){??????????????System.out.println((char)b);??????????}??????}??}???
7、CharArrayReader 和 CharArrayWriter
?? 要想將字符型數據臨時存入緩沖區中,還可以使用 JDK 提供的 CharArrayReader 和 CharArrayWriter,CharArrayReader 是從字符數組中讀取數據,CharArrayWriter 是在內存中創建一個字符數組緩沖區,他們的功能與 ByteArrayInputStream 和 ByteArrayOutputStream 類似,只不過操作的數據是字符。
?
[java]?view plain?copy
class?ByteInputStreamStreamDemo{??????public?static?void?main(String[]?args){??????????FileReader?fr?=?new?FileReader("src.txt");??????????CharArrayWriter?cw?=?new?CharArrayWriter();??????????int?b;??????????while((b=fr.read())!=-1){??????????????cw.write(b);??????????}??????????fr.close();??????????cw.close();????????????char[]?c?=?cw.toCharArray();??????????CharArrayReader?cr?=?new?CharArrayReader(c);??????????int?i;??????????while((i=cr.read())!=-1){??????????????System.out.println((char)i);??????????}??????}??}???
8、SequenceInputStream
?? 如果希望多個流處理數據,這時需要將這些流合并,SquenceInputStream 類可以講幾個輸入流傳亮在一起,合并為一個輸入流。
?
[java]?view plain?copy
class?SequenceInputStreamStreamDemo1{??????public?static?void?main(String[]?args){??????????FileInputStream?in1?=?new?FileInputStream("src1.txt");??????????FileInputStream?in2?=?new?FileInputStream("src2.txt");??????????SequenceInputStream?sis?=?new?SequenceInputStream(in1,in2);????????????FileOutputStream?out?=?new?FileOutputStream("dex.txt");????????????int?len;??????????byte[]?buf?=?new?byte[1024];??????????while((len=sis.read(buf))!=-1){??????????????out.write(buf,0,len);??????????????out.write("\r\n".getBytes());??????????}??????????sis.close();??????????out.close();??????}??}???
?
[java]?view plain?copy
class?SequenceInputStreamStreamDemo2{??????public?static?void?main(String[]?args){??????????FileInputStream?in1?=?new?FileInputStream("src1.txt");??????????FileInputStream?in2?=?new?FileInputStream("src2.txt");??????????FileInputStream?in3?=?new?FileInputStream("src3.txt");????????????Vector?vector?=?new?Vector();??????????vector.addElement(in1);??????????vector.addElement(in2);??????????vector.addElement(in3);??????????Enumeration?en?=?vector.elements();??????????SequenceInputStream?sis?=?new?SequenceInputStream(en);????????????FileOutputStream?out?=?new?FileOutputStream("dex.txt");??????????int?len;??????????byte[]?buf?=?new?byte[1024];??????????while((len=sis.read(buf))!=-1){??????????????out.write(buf,0,len);??????????}??????????sis.close();??????????out.close();??????}??}???
四、File 類
1、File 類的常用方法
?? File 類用于封裝一個路徑,這個路徑可以是從系統盤符開始的絕對路徑,也可以是當前目錄而言的相對路徑。File 類內部封裝的路徑可以指向一個文件,也可以指向一個目錄,在 File 類中提供了針對這些文件或目錄的一些常規操作。
???File 類常用的構造方法:
??File 類常用方法:
?
[java]?view plain?copy
class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("example.txt");??????????System.out.println("文件名稱:"+file.getName());??????????System.out.println("文件的相對路徑:"+file.getPath());??????????System.out.println("文件的絕對路徑:"+file.getAbsolutePath());??????????System.out.println("文件的父路徑:"+file.getParent());??????????System.out.println(file.canRead()?"文件可讀":"文件不可讀");??????????System.out.println(file.canWrite()?"文件可寫":"文件不可寫");??????????System.out.println(file.isFile()?"是一個文件":"不是一個文件");??????????System.out.println(file.isDirectory()?"是一個目錄":"不是一個目錄");??????????System.out.println(file.isAbsolute()?"是絕對路徑":"不是絕對路徑");??????????System.out.println("最后修改的時間為:"+file.lastModified());??????????System.out.println("文件大小為:"+file.length()+"KB");??????????System.out.println("是否成功刪除文件"+file.delete());??????}??}???
2、遍歷目錄下的文件
?? File 類中有一個 list() 方法,該方法用于遍歷某個指定目錄下的所有文件的名稱。
?
[java]?view plain?copy
class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("d:\\java\\bin");??????????if(file.isDirectory()){??????????????String[]?names?=?file.list();??????????????for(String?name:names)??????????????????System.out.println(name);??????????}??????}??}???
?? 有時候程序只需要指定類型的文件,針對這種需求,File?類提供了一個重載的?list(FilenameFilter?filter)?方法。FilenameFilter?是一個接口,被稱作文件過濾器,其中定義了一個抽象方法?accept(File?dir,String?name)?,在調用?list()?方法時,需要實現文件過濾器,在?accept()?方法中做出判斷,從而獲得指定類型的文件。
?
[java]?view plain?copy
class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("d:\\java\\bin");??????????FilenameFilter?filter?=?new?FilenameFileter(){??????????????public?boolean?accept(File?dir,String?name){??????????????????File?currFile?=?new?File(dir,name);??????????????????if(currFile.isFile()?&&?name.endsWith(".java"))??????????????????????return?true;??????????????????else??????????????????????return?false;??????????????}??????????};??????????if(file.exists()){??????????????String[]?lists?=?file.list(filter);??????????????for(String?name:lists){??????????????????System.out.println(name);??????????????}??????????}??????}??}???
???在一個目錄下,除了文件,還有子目錄,如果想得到所有子目錄下的?File?類型對象,需要使用?listFiles()?方法,該方法返回一個?File?對象數組。當對?數組中的元素進行遍歷時,如果元素中還有子目錄需要遍歷,則需要使用遞歸。??
?
[java]?view plain?copy
class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("d:\\java\\bin");??????????fileDir(file);??????}??????public?static?void?fileDir(File?file){??????????File[]?files?=?file.listFiles();??????????for(File?file:files){??????????????if(file.isDirectory()){??????????????????fileDir(file);??????????????}??????????????System.out.println(file.getAbsolutePath());??????????}??????}??}???
?
3、刪除文件及目錄
?
?? 在操作文件時,經常需要刪除一個目錄下的某個我呢間或者刪除整個目錄,這時可以使用?File?類的?delete()?方法。
[java]?view plain?copy
class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("d:\\java\\bin");??????????if(file.exists())??????????????System.out.println(file.delete());??????}??}???? 為什么會輸出?false?呢??那是因為?File?類的?delete()?方法只是刪除一個指定的文件,加入?File?對象嗲表目錄,并且目錄下包含子目錄或文件,則?File?類的?delete()?方法不允許對這個目錄直接刪除。
?
?? 這種情況下,需要通過遞歸的方式將整個目錄以及其中的文件全部刪除。
[java]?view plain?copy
import?java.io.*;??class?FileDemo{??????public?static?void?main(String[]?args){??????????File?file?=?new?File("f:\\java\\bin");??????????deleteDir(file);??????}??????public?static?void?deleteDir(file){??????????if(dir.exists()){??????????????File[]?files?=?dir.listFiles();??????????????for(File?file:files){??????????????????if(file.isDirectory()){??????????????????????deleteDir(file);??????????????????}else{??????????????????????file.delete();??????????????????}??????????????}??????????????dir.delete();??????????}??????}??}???
?? 需要注意的是,在?Java?中刪除目錄時從虛擬機直接刪除而不走回收站,文件將無法恢復,因此在進行刪除操作的時候需要格外小心。
?
五、RandomAccessFile
?
???RandomAccessFile?不屬于流類,但是具有讀寫文件數據的功能,可以隨機從文件的任何位置開始執行讀寫數據的操作。
???RandomAccessFile?的構造方法:
??file或name指定關聯的文件,mode參數指定訪問文件的模式,mode有四個之,最常用的有兩個,分別是r和rw,其中r表示以只讀的方式打開文件,rw表示以讀寫的方式打開文件。
??RandomAccessFile類針對文件的隨機操作,提供了一系列用于定位文件位置的方法:
[java]?view plain?copy
class?RandomAccessFileDemo{??????public?static?void?main(String[]?args){??????????RandomAccessFile?raf?=?new?RandomAccessFile("time.txt","rw");??????????int?times?=?0;??????????times?=?Integer.parseInt(raf.readLine());??????????if(times<0){??????????????System.out.pritnln("您還可以試用"+?times--?+"次");??????????????raf.seek(0);??????????????raf.writeBytes(times+"");??????????}else{??????????????System.out.println("軟件試用已達到次數");??????????}??????????raf.close();??????}??}???
六、字符編碼
1、常用字符集
?
?? 字符碼表是一種可以方便計算機識別的特殊字符集,它是將每一個字符和一個唯一的數字對應而形成的一張表。
?
2、字符編碼和解碼
?
?? 在Java中經常會出現字符轉換為字節或字節轉換為字符的操作,這兩種操作設計到兩個概念,編碼(Encode)和解碼(Decode)。一般來說,把字符串轉換成計算機識別的自己序列稱為編碼,而把字節序列轉換成普通人能夠看懂的字符串稱為解碼。
- 字節數組轉字符串:String(byte[]?bytes,String?charsetName)
- 字符串轉字節數組:String類的getBytes(String?charsetName)方法
?
[java]?view plain?copy
class?RandomAccessFileDemo{??????public?static?void?main(String[]?args){??????????//解碼??????????String?str?=?"傳智播客";????????????byte[]?b1?=?str.getBytes();??????????byte[]?b2?=?str.getBytes("GBK");??????????System.out.println(Arrays.toString(b1));??????????System.out.println(Arrays.toString(b2));????????????????????//編碼??????????byte[]?b3?=?str.getBytes("UTF-8");????????????String?result1?=?new?String(b1,"GBK");??????????System.out.println(result1);????????????String?result2?=?new?String(b2,"GBK");??????????System.out.println(result2);????????????String?result3?=?new?String(b3,"UTF-8");??????????System.out.println(result3);????????????String?result4?=?new?String(b1,"ISO8859-1");??????????System.out.println(result4);??????}??}???
?
?? 在上述的例子中嘗試使用ISO8859-1碼表對GBK編碼的數組進行解碼,出現了亂碼問題,那么亂碼問題該如何解決呢?
???為了解決這種亂碼問題,可以逆向思維,把亂碼字符按照ISO8859-1進行編碼,得到與第一次編碼相同的字節,然后按照正確的碼表GBK對字符進行解碼。
?
[java]?view plain?copy
class?RandomAccessFileDemo{??????public?static?void?main(String[]?args){??????????String?str?=?"傳智";??????????byte[]?b?=?str.getBytes("GBK");??????????//通過ISO8859-1解碼,得到的字符串時亂碼??????????String?temp?=?new?String(b,"ISO8859-1");??????????System.out.println(temp);??????????//試用ISO8859-1對亂碼進行編碼??????????byte[]?b1?=?temp.getBytes("ISO8859-1");??????????//使用GBK將得到的字節數組解碼得到正確的字符串??????????String?result?=?new?String(b1,"GBK");??????????System.out.rpitnln(result);??????}??}???
?
3、字符傳輸
?
?
?? 通過構造函數InputStreamReader(InputStream?in,String?charsetName)和OuputStreamWriter(OutputStream?out,String?charsetName)創建流對象時,可以對需要讀寫的數據指定編碼格式。
[java]?view plain?copy
class?RandomAccessFileDemo{??????public?static?void?main(String[]?args){??????????Reader?reader?=?new?InputStreamReader(new?InputStream("d:\\1.txt"),"GBK");??????????Writer?writer?=?new?OutputStreamWriter(new?OutputStream("f:\\2.txt"),"ISO8859-1");??????????char[]?chs?=?new?char[100];??????????int?len;??????????len?=?reader.read(chs);??????????String?str?=?new?String(chs,0.len);??????????writer.write(str);??????????reader.close();??????????writer.close();??????}??} ?
轉載于:https://my.oschina.net/architectliuyuanyuan/blog/1610029
總結
以上是生活随笔為你收集整理的IO(输入输出)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。