文章目錄
- File類中的主要方法和常量
- 操作流程
- 位元組輸出資料流:OutputStream
- 位元組輸入資料流:InputStream
- 字元輸出資料流:Writer
- 字元輸入資料流:Reader
File類
在整個io包中,唯一表示與檔案本身有關的類就是File類。使用File類可以進行建立或刪除檔案等常用操作,要想使用File類,則首先要觀察File類的構造方法,此類的常用構造方法如下
public File(String pathname)執行個體化File類的時候,必須設定好路徑根據路徑找到檔案
File類中的主要方法和常量
方法或常量 |
類型 |
描述 |
public static final String pathSeparator |
常量 |
表示路徑的分隔字元(windows:‘;’) |
public static final String separator |
常量 |
表示路徑分隔字元(windows:‘\’) |
public File(String pathname) |
構造 |
建立File類對象,傳入完整的路徑 |
public boolean createNewFile() throws IOException |
普通 |
建立新檔案 |
public boolean exists() |
普通 |
判斷檔案是否存在 |
public boolean delete() |
普通 |
刪除檔案 |
public boolean isDirectory() |
普通 |
判斷給定的路徑是否是一個目錄 |
public long length() |
普通 |
返迴文件的大小 |
public String[] list() |
普通 |
列出指定目錄的全部內容,只是名稱 |
public File[] listFiles() |
普通 |
列出指定目錄的全部內容,會列出路徑。 |
public boolean mkdir() |
普通 |
建立一個目錄 |
public boolean renameTo(File dest) |
普通 |
為已有的檔案重新命名 |
程式碼範例:
import java.io.*;public class FileDemo01{public static void main(String args[]){File file=new File("d:"+File.separator+"test.txt");System.out.println("file.pathSeparator:"+file.pathSeparator);//調用靜態變數System.out.println("file.separator:"+file.separator);//調用靜態變數if(file.exists()){//判斷當前檔案是否存在file.delete();//存在就刪除}try{file.createNewFile();//刪除後重新建立}catch(IOException e){e.printStackTrace();}System.out.println("檔案的大小:"+file.length());//輸出新建立檔案的大小}}
程式碼範例2:
import java.io.*;public class FileDemo02{public static void main(String args[]){File file=new File("d:"+File.separator+"test");file.mkdir();//建立新的檔案夾File f=new File("d:"+File.separator+"test.txt");f.renameTo(new File("d:"+File.separator+"test1.txt"));//為已知的檔案重新命名}}
案例:列出指定目錄的全部檔案
import java.io.File ;import java.io.IOException ;public class FileDemo03{public static void main(String args[]){File my = new File("d:" + File.separator) ;// 操作路徑print(my) ;}public static void print(File file){// 遞迴調用if(file!=null){// 判斷對象是否為空白if(file.isDirectory()){// 如果是目錄File f[] = file.listFiles() ;// 列出全部的檔案if(f!=null){// 判斷此目錄能否列出for(int i=0;i<f.length;i++){print(f[i]) ;// 因為給的路徑有可能是目錄,所以,繼續判斷}}}else{System.out.println(file) ;// 輸出路徑}}}};位元組流與字元流
在java.io包中操作檔案內容的主要有兩大類:位元組流、字元流。兩類都分為輸入和輸出操作。在位元組流中輸出資料主要是使用OutputStream完成,輸入使用的是InputStream,在字元流中輸出主要是使用Writer類完成,輸入主要是使用Reader類完成。
流
在程式中所有的資料都是以流的方式進行傳輸或儲存的,程式需要資料的時候要使用輸入資料流讀取資料,而當程式需要將一些資料儲存 起來的時候,就要使用輸出資料流完成。
操作流程
在java中IO操作也是有相關步驟的,以檔案操作為例,主要的操作流程如下:
•A、使用File類開啟一個檔案•B、通過位元組流或字元流的子類,指定輸出的位置•C、進行讀\寫操作•D、關閉輸入\輸出
位元組流
位元組流主要是操作byte類型資料,也byte數組為準,主要操作類就是
·位元組輸出資料流:OutputStream
·位元組輸入資料流:InputStream
位元組輸出資料流:OutputStream
OutputStream類是整個io包中位元組輸出資料流的最大父類,此類的定義如下:
public abstract class OutputStream extends Object implements Closeable, Flushable•Closeable:表示可以關閉的操作,因為程式到最後肯定要關閉。•Flushable:表示重新整理,清空記憶體中的資料。
從以上類的定義中可以發現,此類是一個抽象類別,如果要想使用此類的話,則首先必須通過子類執行個體化對象,那麼如果現在要操作一個檔案,則可以使用FileOutputStream類。通過向上轉型之後,可以為OutputStream執行個體化。
OutputStream類中的常用方法:
方法描述public void close() throws IOException關閉輸出資料流public void flush() throws IOException重新整理緩衝區public void write(byte[] b) throws IOException將一個byte數組寫入資料流public void write(byte[] b,int off,int len)throws IOException將一個指定範圍的byte數組寫入資料流public abstract void write(int b) throws IOException將一個位元組資料寫入資料流
要想使用以上的方法,必須使用子類進行執行個體化,此時使用FileOutputStream子類,此類的構造方法如下:
public FileOutputStream(File file) throws FileNotFoundException
程式碼範例:建立檔案並寫入字元
import java.io.*;public class OutputStreamDemo01{public static void main(String args[])throws Exception{//1、使用File類指定一個檔案名稱File file=new File("d:"+File.separator+"test.txt");//2、建立OutputStream類,並為此執行個體化對象OutputStream out=new FileOutputStream(file);//3、執行寫入操作String str="Hello world";byte b[]=str.getBytes();out.write(b);//4、關閉輸入資料流out.close();}}
註:
1、 在操作的時候如果檔案本身不存在,則會為使用者自動建立新檔案。
2、 如果要追加的內容需要換行,則在內容中加入“\r\n”就可以了。
以上的操作在寫入資料之後,檔案之前的內容已經不存在了,因為在IO操作中預設的情況是將其進行覆蓋的,如果現在想執行追加的功能,則必須設定追加的操作,此時可以通過FileoutputStream向檔案中追加內容:其另外的一個構造方法:
FileOutputStream(File file, boolean append)
在構造方法中,如果將append的值設定為true,則表示在檔案的末尾追加內容。
OutputStream out=new FileOutputStream(file,true);
位元組輸入資料流:InputStream
既然程式可以向檔案中寫入內容,則就可以通過InputStream從檔案中把內容讀取進來,首先來看InputStream類的定義:
public abstract class InputStream extends Object implements Closeable
和OutputStream一樣,InputStream本身也是一個抽象類別,必須依靠其子類,如果現在是從檔案中讀取,子類肯定是FileInputStream。構造方法:
public FileInputStream(File file) throws FileNotFoundException
InputStream類的常用方法:方法描述public int available() throws IOException可以取得輸入檔案的大小public void close() throws IOException關閉輸入資料流public abstract int read() throws IOException讀取內容,以數位方式讀取public int read(byte[] b) throws IOException將內容讀到byte數組之中,同時返回個數
範例程式碼:
import java.io.File ;import java.io.InputStream ;import java.io.FileInputStream ;public class InputStreamDemo01{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象InputStream input = null ;// 準備好一個輸入的對象input = new FileInputStream(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行讀操作byte b[] = new byte[1024] ;// 所有的內容都讀到此數組之中input.read(b) ;// 讀取內容// 第4步、關閉輸出資料流input.close() ;// 關閉輸出資料流System.out.println("內容為:" + new String(b)) ;// 把byte數組變為字串輸出}};
以上代碼對檔案中的內容讀取了出來,但是數組開闢的空間遠遠要大於檔案實際佔用的空間,則此時可以根據讀取檔案的大小來開闢數組空間:
import java.io.File ;import java.io.InputStream ;import java.io.FileInputStream ;public class InputStreamDemo03{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象InputStream input = null ;// 準備好一個輸入的對象input = new FileInputStream(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行讀操作 // byte b[] = new byte[input..available()] ; 跟使用下面的代碼是一樣的byte b[] = new byte[(int)f.length()] ;// 數組大小由檔案決定int len = input.read(b) ;// 讀取內容// 第4步、關閉輸出資料流input.close() ;// 關閉輸出資料流\System.out.println("讀入資料的長度:" + len) ;System.out.println("內容為:" + new String(b)) ;// 把byte數組變為字串輸出}};
另一種讀取方法:
import java.io.File ;import java.io.InputStream ;import java.io.FileInputStream ;public class InputStreamDemo05{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象InputStream input = null ;// 準備好一個輸入的對象input = new FileInputStream(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行讀操作byte b[] = new byte[1024] ;// 數組大小由檔案決定int len = 0 ; int temp = 0 ;// 接收每一個讀取進來的資料while((temp=input.read())!=-1){// 表示還有內容,檔案沒有讀完b[len] = (byte)temp ;len++ ;}// 第4步、關閉輸出資料流input.close() ;// 關閉輸出資料流\System.out.println("內容為:" + new String(b,0,len)) ;// 把byte數組變為字串輸出}};
以上的讀取方式在都是比較常見的。
字元流
在程式中一個字元等於2個位元組,那麼java提供了Reader、Writer兩個專門操作字元流的類。
·字元輸出資料流:Writer
·字元輸入資料流:Reader
字元輸出資料流:Writer
Writer本身是一個字元流的輸出類,此類的定義如下:
public abstract class Writer extends Object implements Appendable, Closeable, Flushable
此類本身也是一個抽象類別,如果要想使用此類,則肯定要使用其子類,此時如果是向檔案中寫入內容,所以應該使用FileWriter子類。構造方法如下:
public FileWriter(File file) throws IOException
Writer類的常用方法:
方法或常量描述public abstract void close() throws IOException關閉輸出資料流public void write(String str) throws IOException將字串輸出public void write(char[] cbuf) throws IOException將字元數組輸出public abstract void flush() throws IOException強制性清空緩衝
範例程式碼:(字元流可以直接輸出字串,不需要轉換為位元組)
import java.io.File ;import java.io.Writer ;import java.io.FileWriter ;public class WriterDemo01{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象Writer out = null ;// 準備好一個輸出的對象out = new FileWriter(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行寫操作String str = "Hello World!!!" ;// 準備一個字串out.write(str) ;// 將內容輸出,儲存檔案// 第4步、關閉輸出資料流out.close() ;// 關閉輸出資料流}};
此時如果是想追加內容,與FileInputStream的格式是一樣的,添加appemd屬性為true;
字元輸入資料流:Reader
Reader本身是一個字元流的輸入類,此類的定義如下:
public abstract class Reader extends Object implements Closeable, Readable;
此類本身也是一個抽象類別,如果要想使用此類,則肯定要使用其子類,此時如果是向檔案中寫入內容,所以應該使用FileReader子類。構造方法如下:
public FileReaderr(File file) throws IOException
Writer類的常用方法:
方法或常量描述public abstract void close() throws IOException關閉輸出資料流public int read() throws IOException讀取單個字元public int read(char[] cbuf) throws IOException將內容讀到字串數組中,返回讀入的長度
範例程式碼:(以字元數組的形式讀取出資料)
import java.io.File ;import java.io.Reader ;import java.io.FileReader ;public class ReaderDemo01{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象Reader input = null ;// 準備好一個輸入的對象input = new FileReader(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行讀操作char c[] = new char[1024] ;// 所有的內容都讀到此數組之中int len = input.read(c) ;// 讀取內容// 第4步、關閉輸出資料流input.close() ;// 關閉輸出資料流System.out.println("內容為:" + new String(c,0,len)) ;// 把字元數組變為字串輸出}};
位元組流在操作的時候本身是不會用到緩衝區(記憶體)的,是與檔案本身直接操作的,而字元流在操作的時候使用到緩衝區的。
通過代碼來驗證字元流使用到了緩衝。
import java.io.File ;import java.io.OutputStream ;import java.io.FileOutputStream ;public class OutputStreamDemo05{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象OutputStream out = null ;// 準備好一個輸出的對象out = new FileOutputStream(f) ;// 執行個體化// 第3步、進行寫操作String str = "Hello World!!!" ;// 準備一個字串byte b[] = str.getBytes() ;// 只能輸出byte數組,所以將字串變為byte數組out.write(b) ;// 寫入資料// 第4步、關閉輸出資料流// out.close() ;// 關閉輸出資料流 此處沒有關閉輸出資料流}};
在使用位元組流操作中,即使沒有關閉,最終也是可以輸出的。
import java.io.File ;import java.io.Writer ;import java.io.FileWriter ;public class WriterDemo03{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象Writer out = null ;// 準備好一個輸出的對象out = new FileWriter(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行寫操作String str = "Hello World!!!" ;// 準備一個字串out.write(str) ;// 將內容輸出,儲存檔案// 第4步、關閉輸出資料流// out.close() ;// 此時,沒有關閉}};
以上的內容,沒有輸出任何的內容,也就是說,所有的內容都是儲存在了緩衝區之中,而如果執行關閉輸出資料流的話會強制性的重新整理緩衝區,所以可以把內容輸出。
如果現在假設,沒有關閉的話,也可以手工強制性調用重新整理方法:
public void flush() throws IOException
程式碼範例:
import java.io.File ;import java.io.Writer ;import java.io.FileWriter ;public class WriterDemo04{public static void main(String args[]) throws Exception{// 異常拋出,不處理// 第1步、使用File類找到一個檔案File f= new File("d:" + File.separator + "test.txt") ;// 聲明File對象// 第2步、通過子類執行個體化父類對象Writer out = null ;// 準備好一個輸出的對象out = new FileWriter(f) ;// 通過對象多態性,進行執行個體化// 第3步、進行寫操作String str = "Hello World!!!" ;// 準備一個字串out.write(str) ;// 將內容輸出,儲存檔案// 第4步、關閉輸出資料流out.flush() ;// 強制性清空緩衝區中的內容// out.close() ;// 此時,沒有關閉}};
在所有的硬碟儲存檔案或是進行傳輸的時候都是以位元組的方式進行的。包括圖片也是按位元組完成,而字元只有在記憶體中才會形成。所以在開發中使用位元組的操作是較多的。
範例:檔案拷貝
通過執行該程式拷貝源檔案到目標檔案:
import java.io.* ;public class Copy{public static void main(String args[]){if(args.length!=2){// 判斷是否是兩個參數System.out.println("輸入的參數不正確。") ;System.out.println("例:java Copy 源檔案路徑 目標檔案路徑") ;System.exit(1) ;// 系統退出}File f1 = new File(args[0]) ;// 源檔案的File對象File f2 = new File(args[1]) ;// 目標檔案的File對象if(!f1.exists()){System.out.println("源檔案不存在!") ;System.exit(1) ;}InputStream input = null ;// 準備好輸入資料流對象,讀取源檔案OutputStream out = null ;// 準備好輸出資料流對象,寫入目標檔案try{input = new FileInputStream(f1) ;}catch(FileNotFoundException e){e.printStackTrace() ;}try{out = new FileOutputStream(f2) ;}catch(FileNotFoundException e){e.printStackTrace() ;}if(input!=null && out!=null){// 判斷輸入或輸出是否準備好int temp = 0 ;try{while((temp=input.read())!=-1){// 開始拷貝out.write(temp) ;// 邊讀邊寫}System.out.println("拷貝完成!") ;}catch(IOException e){e.printStackTrace() ;System.out.println("拷貝失敗!") ;}try{input.close() ;// 關閉out.close() ;// 關閉}catch(IOException e){e.printStackTrace() ;}}}}位元組-字元轉換流OutputStreamWriter和InputStreamReader
在整個IO包中,實際上就是位元組流和字元流,但是除了這兩個流之外,還存在一組位元組流-字元流的轉換類。
•OutputStreamWriter:是Writer的子類,將輸出的字元流轉換為位元組流。即:將一個位元組流的輸出對象變為位元組流的輸出對象•InputStreamReader:是Reader的子類,將輸入的位元組流變為字元流,即:將一個位元組流的輸入對象變為字元流的輸入對象。
在OutputStreamWriter類中需要一個位元組流的對象:public OutputStreamWriter(OutputStream out),例如:將位元組的檔案輸出資料流,以字元的形式輸出。
import java.io.*;public class OutputStreamWriterDemo01{public static void main(String args[]) throws Exception{//所有異常拋出File file=new File("d:"+File.separator+"test.txt");Writer writer=null;//字元輸出資料流writer=new OutputStreamWriter(new FileOutputStream(file));//位元組流變為字元流String str="hello world!!!!";writer.write(str);//使用字元流輸出writer.close();}}
讀的時候,也可以使用字元流的形式讀取位元組流的檔案。
import java.io.* ;public class InputStreamReaderDemo01{public static void main(String args[]) throws Exception{File f = new File("d:" + File.separator + "test.txt") ;Reader reader = null ;reader = new InputStreamReader(new FileInputStream(f)) ;// 將位元組流變為字元流char c[] = new char[1024] ;int len = reader.read(c) ;// 讀取reader.close() ;// 關閉System.out.println(new String(c,0,len)) ;}};
對於FileWriter和FileReader的說明:
從JDK文檔中可知FileOutputStream是OutputStream的直接子類,FileInputStream也是InputStream的直接子類,但是在字元流檔案的兩個操作類卻有一些特殊,FileWriter並不是Writer的子類,而是OutputStream的子類,而FileReader也不是Reader的直接子類,是InputStreamReader的子類。