1. 程式人生 > >Java.io流的基本常用類

Java.io流的基本常用類

Java.io包下面的類主要是對檔案的操作,也是我們經常會用到的類,尤其是實現檔案上傳和下載的功能。本文主要介紹該包下常用的類,包括File,inputStream,OutputStream,Reader和Writer。io流的操作依賴於File類,所以本文首先會介紹File的相關知識。

1.File

File物件代表一個檔案實體,其有以下三個常用的建構函式:
String parentPath = "C:\\Users\\Administrator\\Desktop";
String demoPath = "C:\\Users\\Administrator\\Desktop\\demo.txt";
//一個形參,以檔案路徑字串建立File物件
File file1 = new File(demoPath);
//兩個形參,第一個代表父目錄字串,第二個代表子目錄或者檔案字串
File file2 = new File(parentPath,"/dir1");
//兩個形參,第一個代表父檔案物件,第二個是子目錄或者檔案字串
File file3 = new File(file2,"/dir2");
如果以上檔案不存在,我們可以呼叫File類的mkdir()和mkdirs()方法建立資料夾,呼叫createNewFile()方法建立檔案:
String parentPath = "C:\\Users\\Administrator\\Desktop";
String demoPath = "C:\\Users\\Administrator\\Desktop\\demo.txt";
//一個形參,以檔案路徑字串建立File物件
File file1 = new File(demoPath);
if (!file1.exists()){
    //建立一個空檔案
    file1.createNewFile();
}
//兩個形參,第一個代表父目錄字串,第二個代表子目錄或者檔案字串
File file2 = new File(parentPath,"/dir1");
if (!file2.exists()){//判斷該檔案是否存在
    //不存在就建立
    file2.mkdirs();
}
//兩個形參,第一個代表父檔案物件,第二個是子目錄或者檔案字串
File file3 = new File(file2,"/dir2");
if (!file3.exists()){
    //還不存在 ,再次建立
    file3.mkdir();
}
說明:exists()方法用來判斷檔案是否存在,如果不存在,再去建立。           createNewFile()建立一個空檔案,不能建立資料夾。           mkdirs()和mkdir()都是建立資料夾,區別在於前者可以建立多層不存在的資料夾,後者只能建立單層,下面的例子解釋
File file2 = new File(parentPath,"/dir1");
if (!file2.exists()){
    //這裡可以用mkdir()和mkdirs()
    file2.mkdir();
}
File file3 = new File(file2,"/dir2/dir3");
if (!file3.exists()){
    //這裡只能用mkdirs()
    file3.mkdirs();
}
File類還有一下常用的方法:
//列印檔案的絕對路徑
System.out.println(file1.getAbsolutePath());
//檔名
System.out.println(file1.getName());
//得到父目錄
System.out.println(file1.getParent());

2.io流

io流按照單位分成位元組流和字元流,本文按照這個類別分別介紹這種流。
說明 位元組流 字元流
抽象基類 InputStream,OutputStream Reader,Writer
節點流 FileInputStream,FileOutputStream FileReader,FileWriter
緩衝流 BufferedInputStream,BufferedOutputStream BuffredReader,BufferedWriter
資料流 DataInputStream,DataOutputStream  
物件流 ObjectInputStream,ObjectOutputStream  
轉換流   InputStreamReader,OutputStreamReader

隨機訪問流 RandomAccessFile  

2.1 位元組流  位元組流主要是以位元組的方式讀取或者寫入檔案。  2.1.1 FileInputStream和FileOutputStream            FileInputStream是從檔案中讀內容,每次讀都放在緩衝陣列中,然後返回每次讀位元組的長度。如果到檔案尾,則返回-1.
String parentPath = "C:\\Users\\Administrator\\Desktop";
String demoPath = "C:\\Users\\Administrator\\Desktop\\demo.txt";
//一個形參,以檔案路徑字串建立File物件
File file1 = new File(demoPath);
FileInputStream fis = new FileInputStream(file1);
//緩衝陣列,存在每次讀取的位元組,一次讀取1024個
byte[] buffer = new byte[1024];
int length = 0;
while ((length = fis.read(buffer)) != -1){
    System.out.println(new String(buffer,0,length));
}
fis.close();
說明:首先定義緩衝陣列buffer,用來存在每次從檔案中讀取的內容。length是每次讀取得位元組陣列長度,沒有則是-1.呼叫read()方法開始從檔案中讀,迴圈一直到檔案尾。FileInputStream還有三個非常有用的方法: mak(),reset(),skip(),方便我們隨機讀取檔案內容
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[4];
int length = 0;
//1.標記下標為0的位置
bis.mark(0);
//2.讀,下標從0開始
length = bis.read(buffer);
System.out.println(new String(buffer,0,length) );
//3.再次讀
length = bis.read(buffer);
System.out.println(new String(buffer,0,length) );
//4.重置,下標回到上次標記的位置
bis.reset();
//5.讀
length = bis.read(buffer);
System.out.println(new String(buffer,0,length) );
//6.跳過4個位元組
bis.skip(4);
//7.讀
length = bis.read(buffer);
System.out.println(new String(buffer,0,length) );
bis.close();
fis.close();

上面程式碼的步驟,可有下面的示意圖展現:
說明:1.首先檔案中的內容為Icanuseio!,並且呼叫mark()方法標記當前位置。其中,mark是標記的下標位置,pos是讀取的起始位置。 2.經過第二步讀的時候,mark的位置不變,pos向後移動4個位置。 3.再次讀的時候,從上次pos的位置繼續讀取。 4.呼叫reset()方法將下標重置到上次mark的位置,即0,這時pos回到0位置 5.再次讀就是從下標為0的位置讀 6.呼叫skip(4)方法,將pos的值跳過4個位元組,如上圖紅色區域。 7.再次讀,從pos的位置讀 FileOutputStream是向檔案中寫內容,我們需要把內容放在緩衝陣列中.記住每次寫入內容,都是把之前的內容清除後再寫入。
FileOutputStream fos = new FileOutputStream(file1);
//需要寫入檔案的內容
byte[] content = "寫入檔案的內容".getBytes();
//寫
fos.write(content);
fos.close();
2.1.2 BufferedInputStream和BufferedOutputStream BufferedInputStream同樣包含FileInputStream類相同的方法。BufferedOutputStream和FileOutputStream的用法相同,區別在於前者會在檔案尾追加寫入,而後者是清除檔案內容再寫入。 2.1.3 DataInputStream,DataOutputStream      DataInputStream 主要是把8種基本資料型別和字串寫入檔案,再利用DataOutputStream按照寫入的順序讀出來。
//首先向檔案中寫入內容
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);
//寫boolean值
dos.writeBoolean(true);
//寫byte
dos.writeByte(12);
//寫字串
dos.writeBytes("sd444");
//寫字元
dos.writeChar(98);
//寫浮點型資料
dos.writeDouble(1.3);
//寫整型
dos.writeInt(45);
//寫字串
dos.writeUTF("哈哈");
dos.close();
fos.close();
//讀出寫入的內容,順序一致
FileInputStream fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fis);

boolean readBoolean = dis.readBoolean();
System.out.println(readBoolean);
byte readByte = dis.readByte();
System.out.println(readByte);
//這裡bytes陣列的長度應和寫入的字串的長度一致
byte[] bytes = new byte[5];
dis.read(bytes);
System.out.println(new String(bytes));
char readChar = dis.readChar();
System.out.println(readChar);
double readDouble = dis.readDouble();
System.out.println(readDouble);
int readInt = dis.readInt();
System.out.println(readInt);
String readUTF2 = dis.readUTF();
System.out.println(readUTF2);
dis.close();
fos.close();
列印輸出:
true
12
sd444
b
1.3
45
哈哈


注意:1.讀的順序必須和寫的順序一致 2.通過writeBytes()方法寫入字串,讀的時候緩衝陣列的大小應該和字串的長度一樣。標紅所示
2.1.4 ObjectInputStream,ObjectOutputStream DataInputStream,DataOutputStream是操作基本資料型別和字串,但是其不能讀寫其他物件。ObjectInputStream,ObjectOutputStream在資料流的基礎上增加了對物件例項的讀寫操作.注意寫入的物件必須可序列化
//首先向檔案中寫入內容
FileOutputStream fos = new FileOutputStream(file);
//建立一個user物件
User user = new User();
user.setAge(12);
user.setBirth(new Date());
user.setName("小明");
//將物件寫入檔案中
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(user);
oos.close();

//讀取物件
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
User user1 = (User) ois.readObject();
System.out.println(user1);
ois.close();
fis.close();


2.2 字元流 2.2.1 FileReader,FileWriter  字元流與位元組流的區別在於,字元流每次讀或寫是以char為單位,而不是byte,說明速度更快。
//首先向檔案中寫入內容
FileWriter fw = new FileWriter(file);
fw.write("hello");
fw.close();

//讀取物件
FileReader fr = new FileReader(file);
char[] buffer = new char[1024];
int length =0 ;
while ((length = fr.read(buffer)) != -1){
    System.out.println(new String(buffer,0,length));
}


2.2.2 BuffredReader,BufferedWriter      這兩個緩衝流的速度回更快,每次可以讀取一行,但是隻能對文字操作。BufferedWriter在檔案尾追加內容。
//首先向檔案中寫入內容
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("祝大家國慶快樂!");
bw.write("祝大家國慶快樂!");
bw.close();
fw.close();

//讀取
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String buffer = null;
while ((buffer = br.readLine()) != null){
    System.out.println(buffer);
}

2.2.3 InputStreamReader,OutputStreamReader
轉換流主要是將位元組流轉成字元流,以提高操作檔案的速度。而且在專案開發過程中,我們一般只能獲得物件的位元組流。
FileInputStream fis = new FileInputStream(file);
//位元組流向字元流轉換
InputStreamReader isr = new InputStreamReader(fis);
//通過轉換流建立字元流物件
BufferedReader br = new BufferedReader(isr);

3.RandomAccessFile

上述的位元組流和字元流都需要兩個物件來操作一個檔案。而隨機訪問流只需一個物件即可,並且可以在任何一個位置進行讀寫操作。該類主要用在大檔案上傳的場景中,該場景中大檔案被分成幾份上傳,到後臺我們需要把分散的檔案組合在一起。
RandomAccessFile raf = new RandomAccessFile(file,"rw");
//不會清楚檔案原來的內容,從開始覆蓋
String content = "abcdefghijk";
raf.writeUTF(content);
//設定下標
raf.seek(content.length());
//從當前下標寫
raf.writeUTF("123");
raf.close();
RandomAccessFile raf2 = new RandomAccessFile(file,"rw");

String readLine = raf2.readLine();
System.out.println(readLine);
raf2.close();
總結:點滴成河,記錄每次的學習經歷。本文主要介紹了java.io包下對檔案操作的相關知識,比較常用的是FileInputStream和BufferedReader.