1. 程式人生 > >javaFile類和IO輸入輸出流中隨機讀寫類RandomAccessFile類的講解

javaFile類和IO輸入輸出流中隨機讀寫類RandomAccessFile類的講解

今天來複習一下IO流的api,
在java中用io流來進行檔案的輸出和輸出操作,那麼首先類講解一下什麼是輸入和輸出:

所有往記憶體中送資料都是輸入
所有從記憶體出資料都是輸出

能用java.io包中的api操作的輸入輸出:
記憶體–>外存(硬碟,光碟,U盤) 本地流輸出
記憶體<—外存 本地流輸入
記憶體–>網路上 網路流輸出
記憶體<—網路上 網路流輸入

一般的網路流的應用場景就是檔案的上傳的下載
上傳檔案:先是本地流輸入(從硬碟把資料讀入到記憶體)
然後是網路流輸出(把記憶體的資料儲存到記憶體)
遠端計算機網路流輸入(把網路的資料儲存到記憶體)
遠端計算機本地流輸出(把記憶體的資料儲存到硬碟)
下載檔案:跟上傳檔案的順序相反
不能用java.io操作如下:
記憶體–>顯示器
記憶體–>CPU
記憶體<–CPU
這裡用一張圖來說明一下,更容易理解


說到這兒就不得不講一下資料的持久化的問題了.
資料的持久化:
-資料長時間保留在硬碟上
-資料長時間儲存在資料庫上,其實資料庫的本質就是資料庫檔案儲存在硬碟上
在硬碟中實際體現出來的是檔案和目錄

File類:專門用來操作目錄和檔案,但是不能操作檔案內容
一批類專門用來操作檔案的內容
根據檔案內容的操作:
位元組流:對檔案的讀寫內容都是用位元組方式操作
字元流:對檔案的讀寫內容都是用字元(ascill)的方式操作

File類:用於表示檔案和目錄,跟內容無關
有關檔案和目錄間的分隔符的問題:
window方式: C:\aa\bb\cc.txt
Linux 方式: /home/soft/aa/bb/cc.txt
java中對於路徑中的分隔符的表示:
window方式: C:\aa\bb\c.txt
Linux方式: /home/soft/aa/bb/cc.txt

如果想相容:(二者都可以,蘿蔔青菜各有所愛)
“aa”+File.separator+”bb”+File.separator+”cc.txt”

File的api:
使用一個類之前首先要看它的構造方法

-構建File類物件:File(String filePath);
File(File parent,String child);
File(String parentName,String child);
它的常用api有:
-isFile():用於判斷當前的File物件所表示的是否是一個標準的檔案
-isDirectory():用於判斷當前File物件所表示的是否是一個目錄

-length():用於返回檔案的長度,如果是目錄,window返回結果是0,不會報異常

-exists():用於測試檔案或目錄是否存在
-createNewFile():用於在當前的目錄中建立一個新的空檔案,返回結果是Boolean值,如果指定的檔案不存在則建立檔案返回true;如果指定的檔案存在,則返回false
-delete():用於刪除指定的目錄或檔案,若此File物件表示一個目錄時,要保證此目錄為空才可刪除
-mkdir():用於建立目錄
-mkdirs():用於建立多層目錄
-listFIles():用於返回指定目錄中的所有子目錄和子檔案
-listFIle(FileFilter):用於返回指定目錄中的資訊,這些資訊由FileFilter來過濾
-listFile(FilenameFileFilter):用於返回指定目錄中的資訊,這些資訊由FilenameFileFilter來過濾
-list():用於返回指定目錄中的所有資訊,資訊中不包括子目錄和子檔案的路徑資訊

File類中有一個很重要的類,就是RandomAccessFile類:隨機讀寫類
random:隨機
access:訪問/讀寫/儲存
file:檔案
RandomAccessFile類可以對檔案做隨機讀寫操作,可以通過seek方法設定指標的位置,然後從指標的位置開始讀取位元組
seek:搜尋/探索/尋找/尋求
RandomAccessFile類檔案的隨機訪問有兩種模式:mode
**-只讀模式:r
-讀寫模式:rw**
建立物件:RandomAccessFile(File file,String mode);//建立從中讀取和向其中寫入的隨機訪問流,檔案指定由File類指定
RandomAccessFile(String name,String mode)//建立從中讀取和向其中寫入的隨機訪問流,檔案指定由String 類指定
mode的取值: r 只讀模式 read
rw 讀寫模式 read write
-寫入操作:
void write(int d);此方法會根據當前指標所在的位置處寫入一個位元組,是將int的低8位
void write(byte[] d);此方法可以給檔案中寫入一組位元組,根據當前指標的位置連續寫出給定資料中的所有位元組
byte[] b=”字串”.getBytes();
void write(byte[] b,int offset,int len);將len個位元組從指定byte陣列寫入檔案,並從偏移量offset處開始
-讀取操作:
int read();此方法會從檔案中讀取一個byte位元組來填充int的低8位,返回值是0-255;
如果返回-1,則表示讀取到檔案末尾,每次讀取之後自動移動檔案指標到下一個位元組,準備下次讀取
int read(byte[] b);此方法從指標的位置處嘗試最多讀取給定陣列長度的位元組量,
並從給定的位元組陣列的第一個位置開始,將讀取到的位元組順序
存放在陣列的對應位置,返回的是實際讀到的位元組數,如果讀
到檔案末尾,則返回值為-1
int read(byte[] b,int offset,int len);將最多len個數據位元組從檔案中讀入byte資料,並從偏移量offset開始儲存

-void getFilePointer();返回此檔案中的當前偏移量
-void seek(long position);設定到此檔案開頭測量到檔案指標偏移量,在該位置發生下一個讀取或寫入的操作
-int skipBytes(int n);此方法可能跳過一些較少量的位元組

總結:RandomAccessFile類,此類很特殊,首先是按照位元組操作,其次可以對檔案中的任意位置可以通過seek方法做檔案指標定位

由於File類的方法的使用都比較簡單,就不做例子了,下面把RandomAccessFile類的常用api的使用演示一下:

public class TestRandomAccessFileAPIClass {

    /**
     * 構建RandomAccessFile類物件
     * @throws FileNotFoundException 
     */
    @Test 
    public void testMethod1() throws FileNotFoundException{
        File file1=new File("C:\\Users\\李旭康\\Desktop\\test\\TEST.txt");
        File file2=new File("C:\\Users\\李旭康\\Desktop\\test\\TEST.txt");
        RandomAccessFile raf1=new RandomAccessFile(file1,"r");
        RandomAccessFile raf2=new RandomAccessFile(file2,"rw");
    }

    /**
     * write(int)
     * @throws FileNotFoundException
     */
    @Test
    public void testMethod2() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        raf.write(55);
        raf.close();
    }
    /**
     * int Read()
     * @throws Exception
     */
    @Test
    public void testMethod3() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"r");
        int d=raf.read();
        System.out.println(d);
    }
    /**
     * write(byte[] b)
     * @throws Exception
     */
    @Test
    public void testMethod4() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        byte[] b="hello word!".getBytes();
        raf.write(b);
        raf.close();
    }

    /**
     * int read(byte[] b)
     * @throws Exception
     */
    @Test
    public void testMethod5() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"r");
        byte[] b1=new byte[20];
        byte[] b2=new byte[16];
        int d1=raf.read(b1);//從檔案中讀取內容放在位元組陣列中,返回值是讀取的位元組數
        System.out.println(d1);
        System.out.println(new String(b1));
        /*int d2=raf.read(b2);//從檔案中讀取內容放在位元組陣列中,返回值是讀取的位元組數
        System.out.println(d2);
        System.out.println(new String(b2));*/
    }
    /**
     * write(byte[] b,int offset,int len)
     * @throws Exception
     */
    @Test
    public void testMethod6() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        byte[] b="hello word!".getBytes();
        raf.write(b,0,6);
        raf.close();
    }

    /**
     * int read(byte[] b,int offset,int len)
     * @throws Exception
     */
    @Test
    public void testMethod7() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"r");
        byte[] b1=new byte[10];
        int d1=raf.read(b1,0,3);
        System.out.println(d1);
        System.out.println(new String(b1));

    }
    @Test
    public void testMethod8() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        System.out.println(raf.getFilePointer());
        raf.write('a');
        System.out.println(raf.getFilePointer());
        raf.write(1000);
        System.out.println(raf.getFilePointer());
        raf.close();
    }
    /**
     * seek(long)
     * @throws Exception
     */
    @Test
    public void testMethod9() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        raf.seek(2);
        System.out.println(raf.getFilePointer());
        int k=raf.read();
        System.out.println(k);
        System.out.println(raf.getFilePointer());
        raf.seek(2);//重新移回2
        System.out.println(raf.getFilePointer());
        raf.seek(raf.length()-3);
        System.out.println(raf.getFilePointer());
        k=raf.read();
        System.out.println("k="+k);
        System.out.println(raf.getFilePointer());
        raf.close();
    }
    /**
     * int skipBytes(int)
     * @throws Exception
     */
    @Test
    public void testMethod10() throws Exception{
        File file=new File("C:\\Users\\李旭康\\Desktop\\test\\test.txt");
        RandomAccessFile raf=new RandomAccessFile(file,"rw");
        raf.skipBytes(3);
        System.out.println(raf.getFilePointer());
        int k=raf.read();
        System.out.println(k);
        System.out.println(raf.getFilePointer());
        raf.skipBytes(3);
        System.out.println(raf.getFilePointer());
        k=raf.read();
        System.out.println(k);
        System.out.println(raf.getFilePointer());
        raf.close();
    }
}

FIle的IO的方法還有FileOutputStream類和FileOutputStream類,由於這兩個類很重要,本文就先不做講解,我將會在下篇文章中詳細講解.