java之IO處理,javaio

來源:互聯網
上載者:User

java之IO處理,javaio
File檔案基礎

檔案與目錄抽象路徑名稱的表示,其構造方法有四個

File(File parent,String child):從抽象父目錄下建立一個File執行個體。

File(String parent,String child):從父目錄下建立一個File執行個體。

File(String pathname):從指定路徑下建立一個File執行個體。

File(URI path):從URI轉換成抽象路徑下建立一個File執行個體。


listFiles()方法:返回一個抽象路徑名數組,這些抽象路徑名表示目錄中的子項(檔案或目錄)

File file = new File("/home/colin");File[] childs = file.listFiles();

listFiles(FileFilter filter):FileFilter是抽象路徑名的過濾器,可以用於返回過濾器要求的子目錄
File file = new File("/home/colin");//有沒有考慮過,java中不允許實現介面執行個體,但是在匿名內部類中卻實現了介面,比如這個FileFilter介面//實際上如果查看編譯後的代碼(會發現編譯後的代碼中有一個class檔案,這個class實現了這個介面,並重寫了這個介面的方法)//所以這是一種虛擬執行個體化介面,或者理解為間接執行個體化介面。File[] childs = file.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {return pathname.getName().startsWith(".");}});

還有一個listFiles(FilenameFileter filter):FilenameFile用於檢測指定檔案是否包含在特定目錄下

其他API相對簡單了,擷取檔案狀態、建立刪除檔案


RandomAccessFile隨機讀寫檔案

File 執行個體只涉及到對檔案的操作,java提供了可以對檔案隨機訪問的操作,訪問包括讀和寫操作,這種實現是基於指標的操作。

兩個構造方法:

RandomAccessFile(File name,String model)

RandomAccessFile(String name,String model)

model指定的是對檔案隨機訪問操作模式,有兩種模式分別是唯讀模式和讀寫入模式,"r"表示檔案的訪問是唯讀,"rw"表示讀和寫入模式。


RandomAccessFile file = new RandomAccessFile("/home/colin","rw");

寫資料:

write(byte[] b):將指定自己數組b寫到隨機讀寫檔案中,寫到指標的位置

write(byte[] b,int off,int len):指定了起始位置和長度

write(int n):將n的低八位寫到檔案中去

他還有寫入特定特性的方法:writeBoolean(boolean b)、writeInt(int n)、writeDouble(double v)、writeChart(chart c)、writeCharts(String s)、writeByte(int n)、writeBytes(String s)、writeFloat(Float t)等

讀資料:

int read():讀取1byte(8位)放到int的低八位中,高24為為0。如果讀到-1,說明讀到了檔案的末尾

int read(byte[] b):最多讀取b.length個位元組到數組中,返回值為實際讀取到的位元組量

int read(byte[] b,int off, int length):指定讀取數組的起始位置和讀取長度

相應的還有讀取特定類型資料的read

readBoolean()、readFloat()等等,特別還有一個readLine()讀取當前位置的一行

這些都是從當前指標位置開始讀取的

釋放關聯的資源:void close()

擷取當前RandomAccessFile的指標:long getFilePoint(),以位元組為單位,比如如果一個Int是4位

移動當前指標位置:void seek(long pos)

跳過n個位元組:int sikpBytes(int n):返回跳過的實際位元組數,n為負數不跳過任何位元組

RandomAccessFile file = null;try {file = new RandomAccessFile("/home/colin/test.txt","rw");//byte[] b = "this is sample RandomAccessFile".getBytes();//file.read(b);byte[] b = new byte[10];while(file.read(b) >0){System.out.println(new String(b));System.out.println(file.getFilePointer());//擷取檔案指標file.skipBytes(1);//每次讀取跳過一個位元組}} catch (FileNotFoundException e) {e.printStackTrace();}finally{if(file != null)file.close();}


基本IO

輸入是指從外界進入程式方向,即當我們需要讀取資料的時候,使用輸入。

輸出是指從程式發送到外界方向,通常我們需要寫出資料到外界,所以輸出是用來寫資料的。

流的分類

根據單位:位元組流(8bit,圖片視頻等)和字元流(16bit,文本)

根據角色:節點流(直接作用在文本上的流,直接與特定的地方(磁碟、記憶體)相連)和處理流(在節點流外層的流,是對一個已經存在流的串連和封裝,在所封裝的流的功能上實現資料的讀寫)

java中40多種流都是從4個基類派生出來的

            位元組流               字元流

輸入:InputStream     Reader

輸出:OutputStream  Writer


InputStream和OutputStream

二者都是位元組流的抽象基類,定義了基本的read和write方法,read()、read(byte[] a,int off,int length)、read(byte[] b)、write(int b)、write(byte[] b)、write(byte[] b,int off ,int len)

Reader和Writer

reader和writer都是字元流的抽象基類,定義了讀取字元的read和write。read()、read(char[] cbuf)、read(char[] cbuf,int off, int len)、write(char c)、write(char[] cbuf)、cbuf(cbuf,int off ,int len)

檔案流

檔案位元組流:

FileOutputStream可以使用以下幾種方法構造:

FileOUtputStream(File file)     

FileOutputStream(String name)

指定寫入的檔案,如果該檔案存在的化會清除該檔案上面的內容
FileOutputStream(File file,boolean append)

FileOutputStream(String name,boolean append)

如果指定append參數為true,則如果寫入的檔案存在,是以追加的方式進行寫入的

FileInputStream可以使用以下方法構造:

FileInputStream(File file)

FileOutputStream(String name)

檔案位元組流實現了inputStream和outputStream的基本read和write

注意如果讀取的時候返回-1,則說明讀取到了EOF


利用檔案流實現檔案的複製:

File file1 = new File("/home/colin/hello.py");File file2 = new File("/home/colin/hello2.py");FileInputStream input = null;FileOutputStream output = null;try {input = new FileInputStream(file1);output = new FileOutputStream(file2);byte[] b = new byte[10];int len = -1;while((len=input.read(b))!=-1){output.write(b, 0, len);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {                               //先關輸入資料流,再關輸出資料流                                 if(inputput != null)inputput.close();if(output != null)output.close();} catch (IOException e) {e.printStackTrace();}}

FileReader和FileWriter與FileInputStream和FileOutputStream使用方式一樣。

緩衝流

BufferedInputStream原理:緩衝位元組輸入資料流,內部維護一個緩衝區,該流會儘可能一次性讀取若干位元組到緩衝區,然後逐一返回知道緩衝區中的資料被全部讀取完畢,從而減少讀取次數,提高讀取效率,BIS就是一個處理流,該流提供了緩衝功能。他還提供了mark、reset和skip方法

提供的構造方法:

BufferedInputStream(InputStream input)

BufferedInputStream(InputStream input,int size):size指定緩衝區大小


BufferedOutputStream原理:緩衝輸出資料流,內部維護一個緩衝區,每當向該流寫入資料的時候,都會現將資料存放區緩衝區中,當緩衝區已滿的時候,緩衝流會將資料一次性全部寫出。

提供的構造方法:

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int size):指定緩衝區大小

BufferedOutputStream只提供了write和flush()方法,flush()清空緩衝區,將緩衝區中的資料強制寫入。


利用緩衝流實現檔案複製:

BufferedInputStream bis = null;BufferedOutputStream bos = null;try {bis = new BufferedInputStream(new FileInputStream(new File("/home/colin/hello.py")));bos = new BufferedOutputStream(new FileOutputStream(new File("/home/colin/hello3.py")));int len = -1;byte[] b = new byte[10];while((len=bis.read(b)) !=-1){bos.write(b, 0, len);}bos.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{try {//先關輸入資料流,再關輸出資料流if(bis != null)bis.close();if(bos != null)bos.close();} catch (IOException e) {e.printStackTrace();}}

BufferedReader和BufferedWriter與BufferedInputStream和BufferedOutputStream實現原理是一樣的,但是BufferedWriter提供了newLine(),寫入分行符號的方法物件流程

對象序列化:對象存在記憶體中,有時候需要將對象儲存到磁碟上,或者將對象進行傳輸等這樣的操作。這時候需要將對象轉化為一個位元組序列,這個過程稱為對象序列化。

對象還原序列化:有時候需要將位元組序列轉化成為對應的對象,這個過程成為對象的還原序列化。

ObjectOutputStream:用來將對象進行序列化的輸出資料流

提供的構造方法:

ObjectOutputStream()

ObjectOutputStream(OutputStream out)

使用其write方法,將對象轉化成為一個位元組序列後寫出,write方法提供了諸如writeInt()等此類方法。

ObjectInputStream:用來將對象還原序列化

提供的構造方法:

ObjectInputstream()

ObjectInputStream(InputStream input)

使用其提供的readObject()方法,讀取位元組並轉化為對應的對象


這個整體思路是要對對象進行傳遞,需要將對象轉換成為位元組流以便傳輸,所以首先通過ObjectOutputStream進行寫入,將對象寫成位元組進行傳輸。傳遞到目標位置後需要讀取,這時候將傳輸的位元組轉換成為對象。

如果使用ObjectOutputStream進行序列化寫入,需要序列化對象實現Serializable介面,該介面並沒有任何方法只是序列化標誌。通常實現該介面需要給出一個serialVersionUID,表明該類版本,若不顯示聲明編譯器也會經過計算給出一個serialVersionUID,但是不同編譯器實現有所不同,所以如果想要跨平台,都應該顯示聲明版本號碼。當類的對象序列化到磁碟上面,之後隨之需求改變,改變了類的屬性,那麼還原序列化就會出現InvalidClassException,這樣就會造成不相容問題。但當serialVersionUID相同時,會將不一樣的Field以type的預設值還原序列化,可以避開不相容問題

transient關鍵詞:當我們對對對象進行序列化後,得帶的位元組序列往往比較大,有時我們在對一個對象進行序列化時可以忽略某些不必要的屬性,從而對序列化後得到的位元組序列瘦身,可以將其聲明為transient,這樣這些屬性在序列化時會被忽略。

執行個體:

/* *構造Emp類,對其對象進行序列化與還原序列化 */public class Emp implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;private double salary;private transient String description;    //使用transient修飾,在還原序列化時輸出null public Emp(String name,int age,double salary,String description){this.name = name;this.age = age;this.salary = salary;this.description = description;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}@Overridepublic String toString() {return "Emp [name="+name+",age="+age+",salary="+salary+",description="+description+"]";}}/*     * 將Emp對象序列化,並且儲存     */    public static  void testOos(){        ObjectOutputStream oos = null;        try {            FileOutputStream fos = new FileOutputStream(new File("/home/colin/oos.obj"));            oos = new ObjectOutputStream(fos);            Emp emp = new Emp("colin", 23, 13000, "I want you!!!");            oos.writeObject(emp);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }finally{            try {                if(oos != null)                    oos.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    /*     * 將儲存的Emp對象反序列輸出     */    public static void testOis(){        ObjectInputStream ois = null;        try {            FileInputStream fis = new FileInputStream(new File("/home/colin/oos.obj"));            ois = new ObjectInputStream(fis);            Emp emp = (Emp)ois.readObject();            System.out.println(emp.getName()+","+emp.getAge()+","+emp.getSalary()+","+emp.getDescription());        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.