天天看點

java基礎之IO流--RandomAccessFile(也很特殊,直接繼承自Object類)

這哥們既能讀又能寫的原理是:内部封裝了位元組輸入流和位元組輸出流

用途:可是實作資料的分段寫入,一個線程負責一段

此類的執行個體支援對随機通路檔案的讀取和寫入。随機通路檔案的行為類似存儲在檔案系統中的一個大型 byte 數組。存在指向該隐含數組的光标或索引,稱為檔案指針;輸入操作從檔案指針開始讀取位元組,并随着對位元組的讀取而前移此檔案指針。如果随機通路檔案以讀取/寫入模式建立,則輸出操作也可用;輸出操作從檔案指針開始寫入位元組,并随着對位元組的寫入而前移此檔案指針。寫入隐含數組的目前末尾之後的輸出操作導緻該數組擴充。該檔案指針可以通過 getFilePointer 方法讀取,并通過 seek 方法設定。 

通常,如果此類中的所有讀取例程在讀取所需數量的位元組之前已到達檔案末尾,則抛出 EOFException(是一種 IOException)。如果由于某些原因無法讀取任何位元組,而不是在讀取所需數量的位元組之前已到達檔案末尾,則抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被關閉,則可能抛出 IOException

RandomAccessFile(File file, String mode) 

          建立從中讀取和向其中寫入(可選)的随機通路檔案流,該檔案由 File 參數指定。 

RandomAccessFile(String name, String mode) 

          建立從中讀取和向其中寫入(可選)的随機通路檔案流,該檔案具有指定名稱。 

通過構造函數可以看出這哥們局限性是:隻能操作硬碟上的檔案

而且還有模式:

建立從中讀取和向其中寫入(可選)的随機通路檔案流,該檔案由 File 參數指定。将建立一個新的 FileDescriptor 對象來表示此檔案的連接配接。 

mode 參數指定用以打開檔案的通路模式。允許的值及其含意為: 

值 含意

"r" 以隻讀方式打開。調用結果對象的任何 write 方法都将導緻抛出 IOException。  

"rw" 打開以便讀取和寫入。如果該檔案尚不存在,則嘗試建立該檔案。  

"rws" 打開以便讀取和寫入,對于 "rw",還要求對檔案的内容或中繼資料的每個更新都同步寫入到底層儲存設備。  

"rwd"   打開以便讀取和寫入,對于 "rw",還要求對檔案内容的每個更新都同步寫入到底層儲存設備。  

"rws" 和 "rwd" 模式的工作方式極其類似 FileChannel 類的 force(boolean) 方法,分别傳遞 true 和 false 參數,除非它們始終應用于每個 I/O 操作,并是以通常更為高效。如果該檔案位于本地儲存設備上,那麼當傳回此類的一個方法的調用時,可以保證由該調用對此檔案所做的所有更改均被寫入該裝置。這對確定在系統崩潰時不會丢失重要資訊特别有用。如果該檔案不在本地裝置上,則無法提供這樣的保證。 

"rwd" 模式可用于減少執行的 I/O 操作數量。使用 "rwd" 僅要求更新要寫入存儲的檔案的内容;使用 "rws" 要求更新要寫入的檔案内容及其中繼資料,這通常要求至少一個以上的低級别 I/O 操作。 

如果模式為"r" :當檔案不存在時,不會自動建立,會抛出異常

如果模式為“rw”:當檔案不存在時,會自動建立,當檔案存在是不會覆寫

如果存在安全管理器,則使用 file 參數的路徑名作為其參數調用它的 checkRead 方法,以檢視是否允許對該檔案進行讀取通路。如果該模式允許寫入,那麼還使用該路徑參數調用該安全管理器的 checkWrite 方法,以檢視是否允許對該檔案進行寫入通路。 

常用方法:

 FileChannel getChannel() 

          傳回與此檔案關聯的唯一 FileChannel 對象。 

long getFilePointer() 

          傳回此檔案中的目前偏移量。 

 long length() 

          傳回此檔案的長度。 

String readUTF() 

          從此檔案讀取一個字元串。該字元串已使用 UTF-8 修改版格式進行編碼。  

void seek(long pos) 

          設定到此檔案開頭測量到的檔案指針偏移量,在該位置發生下一個讀取或寫入操作。 

 void writeBytes(String s) 

          按位元組順序将該字元串寫入該檔案。 

void writeChars(String s) 

          按字元順序将該字元串寫入該檔案。 

 void writeUTF(String str) 

          使用 modified UTF-8 編碼以與機器無關的方式将一個字元串寫入該檔案。 

void write(byte[] b)  

将 b.length 個位元組從指定 byte 數組寫入到此檔案,并從目前檔案指針開始。

package newFeatures8;


import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo{
	public static void main(String[] args) throws IOException {
		//writeFile();
		readFile();
	}
	
	public static void writeFile(){
		try (RandomAccessFile raf=new RandomAccessFile("randomAccessFile.txt", "rw");){
			raf.write("李四".getBytes());
			/*
			 	向此檔案寫入指定的位元組,在檔案中看到的是字元
			          隻寫出int類型的最低8位,也就是隻寫了一個位元組,而int有4個位元組
			          如果該int數字超出127 則會出現資料丢失,如何解決?
			    //write(int a);
			         使用其writeInt()方法
			 */
			raf.writeInt(97);
			raf.write("王五".getBytes());
			raf.writeInt(99);
			
		} catch (Exception e) {
			throw  new RuntimeException(e);
		}
	}
	
	public static void readFile(){
		try (RandomAccessFile raf=new RandomAccessFile("randomAccessFile.txt", "r");){
			//模式若為"r" 能屏蔽掉寫
			//調整對象中的指針,通過指針的偏移可以擷取檔案中的任意一段資料
			//但是希望你保證這資料是有規律的
			raf.seek(8);
			//raf.skipBytes(8);隻能往前跳
			byte[] buf=new byte[4];
			raf.read(buf);
			int age=raf.readInt();
			System.out.println("name="+new String(buf));
			System.out.println("age="+age);

 			//new String(raf.readline().getBytes("ISO-8859-1"), "utf-8")
			//System.out.println(raf.readLine());不常用,而且此方法不支援完整的 Unicode 字元集
		} catch (Exception e) {
			throw  new RuntimeException(e);
		}
	}
	
}