java IO(File類、字節流與字符流、字節字符轉換流)


轉自(https://www.iteye.com/blog/javawolf-1-2066881)

 

File類
在整個io包中,唯一表示與文件本身有關的類就是File類。使用File類可以進行創建或刪除文件等常用操作,要想使用File類,則首先要觀察File類的構造方法,此類的常用構造方法如下



1. 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的子類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM