java高級應用--File + RandomAccessFile
張孝祥源碼:
import java.io.*; public class RandomFileTest { public static void main(String [] args) throws Exception { Employee e1 = new Employee("zhangsan",23); Employee e2 = new Employee("Lisi",24); Employee e3 = new Employee("Wangwu",25); RandomAccessFile ra=new RandomAccessFile("c://1.txt","rw"); ra.write(e1.name.getBytes()); ra.writeInt(e1.age); ra.write(e2.name.getBytes()); ra.writeInt(e2.age); ra.write(e3.name.getBytes()); ra.writeInt(e3.age); ra.close(); RandomAccessFile raf=new RandomAccessFile("c://1.txt","r"); int len=8; raf.skipBytes(12); //跳過第一個員工的信息,其中姓名8字節,年齡4字節 System.out.println("第二個員工信息:"); String str=""; for(int i=0;i<len;i++) str=str+(char)raf.readByte(); System.out.println("name:"+str); System.out.println("age:"+raf.readInt()); System.out.println("第一個員工的信息:"); raf.seek(0); //將文件指針移動到文件開始位置 str=""; for(int i=0;i<len;i++) str=str+(char)raf.readByte(); System.out.println("name:"+str); System.out.println("age:"+raf.readInt()); System.out.println("第三個員工的信息:"); raf.skipBytes(12); //跳過第二個員工信息 str=""; for(int i=0;i<len;i++) str=str+(char)raf.readByte(); System.out.println("name:"+str.trim()); System.out.println("age:"+raf.readInt()); raf.close(); } } class Employee { String name; int age; final static int LEN=8; public Employee(String name,int age) { if(name.length()>LEN) { name = name.substring(0,8); } else { while(name.length()<LEN) name=name+"/u0000"; } this.name=name; this.age=age; } }
File類
。File類是io包中唯一代表磁盤文件本身信息的類,而不是文件中的內容
。File類定義了一些與平台無關的方法來操縱文件,例如創建、刪除、文件和重命名文件
。Java中的目錄被當做一種特殊的文件使用,list方法可以返回目錄中的所有子目錄和文件名
。在unix下的路徑分隔符為/,在dos下的路徑分隔符為/,java可以正確處理unix和dos的路徑分隔符。
。編程舉例:判斷某個文件是否存在,如果存在就刪除,並新建。
package File; import java.io.*; import java.util.Date; public class FileTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub File f = new File("1.txt"); if(f.exists()){ f.delete(); System.out.println("刪除已存在文件"); } else{ try { f.createNewFile(); System.out.println("文件名字:"+ f.getName()); System.out.println("文件路徑:"+ f.getPath()); System.out.println("文件絕對路徑(完整的目錄):"+ f.getAbsolutePath()); System.out.println("文件父目錄:"+ f.getParent()); System.out.println(f.exists()?"文件存在":"文件不存在"); System.out.println(f.canRead()?"可讀":"不可讀"); System.out.println(f.isDirectory()?"f是個目錄":"f不是個目錄"); System.out.println("文件的最後修改時間:"+ new Date(f.lastModified())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
RandomAccessFile類
。RandomAccessFile類提供了眾多的文件訪問方法
。RandomAccessFile類支持隨機訪問方式
(可應用於多線程下載 、 斷點續傳)
。RandomAccessFile類在隨機(相對順序而言)讀寫等長記錄格式的文件有很大優勢
。RandomAccessFile類僅限於操作文件,不能訪問其他的io設備,如網絡、內存映像等
。兩種構造方法:
New RandomAccessFile(f,”rw”); //讀寫方式
New RandomAccessFile、(F,”R”)//隻讀方式
。編程實例:
往文件寫入三條記錄,以非順序讀取
實體員工類:
package RandomAccessFile; /* * 員工實體類 * 每個員工包含8個字符(16個字節)的name和4個字節的age * 故每個員工類占用20字節的空間 */ public class Employee { private String name ; //員工姓名 private int age; //員工年齡 public static final int LEN = 8; //員工姓名的定長,8個字節 public Employee(String name, int age) {// if(name.length()>8){//判斷員工姓名是否是8個字節,超過則截取,不足則補空 name = name.substring(0, LEN); }else{ while(name.length()<LEN){ name += "/u0000";//補上空格 } } this.name = name; this.age = age; } 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; } }
隨機讀寫測試一:
/** * 不支持漢字的處理 */ package RandomAccessFile; import java.io.RandomAccessFile; /** * @author Administrator * */ public class RandomAccessTest { /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Employee em1 = new Employee("zhangsan",23); Employee em2 = new Employee("lisi",24); Employee em3 = new Employee("wangwu",25); //新建隨機存儲文件,並將員工信息依次寫入 RandomAccessFile ran = new RandomAccessFile("random.txt","rw");//已讀寫的方式新建random文件 ran.write(em1.getName().getBytes());//將姓名轉換成字節數組形式,寫入文本 ran.writeInt(em1.getAge());//以int的四個字節的形式寫入文本 ran.write(em2.getName().getBytes()); ran.writeInt(em2.getAge()); ran.write(em3.getName().getBytes()); ran.writeInt(em3.getAge()); ran.close(); //測試隨機讀取 int len = 0; byte[] buf = new byte[8]; //int age = 0; String name = null; RandomAccessFile ranr = new RandomAccessFile("random.txt","r"); //先讀第二個記錄 ranr.skipBytes(Employee.LEN+4);//先跳過12個字節 len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 name = new String(buf,0,len);//將buf數組寫入name字符流 System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 //在讀第一個記錄 ranr.seek(0);//絕對定位到0上 len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 name = new String(buf,0,len);//將buf數組寫入name字符流 System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 //最後讀第三個記錄 ranr.skipBytes(Employee.LEN+4);//再跳過12個字節 len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 name = new String(buf,0,len);//將buf數組寫入name字符流 System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 ranr.close(); } }
隨機讀寫測試二:
/** * */ package RandomAccessFile; import java.io.RandomAccessFile; /** * @author Administrator * */ public class RandomAccessTest2 { /** * * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Employee em1 = new Employee("張三",23); Employee em2 = new Employee("李四",24); Employee em3 = new Employee("wangwu",25); //新建隨機存儲文件,並將員工信息依次寫入 RandomAccessFile ran = new RandomAccessFile("random2.txt","rw");//已讀寫的方式新建random文件 /* * 注意: * 因為在java中無論一個漢字還是一個字母都是一樣的,都占用兩個字節, * 經過上麵employee的構造聲明,其中em1和em2中實際占用2*2+6*2+4=20個字節,em3占用6*2+2*2+4=20個字節; * 當以write+writeint形式寫入name+age時em1和em2實際占用2*2+6+4=14個字節 * 而em3實際占用6+2+4=12個字節 * 因此照成了三條記錄的不等長 * * 注意:其中 * getbytes函數使用平台默認的字符集將 String 解碼為字節序列,其中漢字保持兩個字節的體積,而字母則變成一個字節,並將結果存儲到一個新的字節數組中。 * write函數將 b.length 個字節從指定字節數組寫入到此文件,並從當前文件指針開始 * * ran.write(em1.getName().getBytes());//將姓名轉換成字節數組形式,寫入文本 ran.writeInt(em1.getAge());//以int的四個字節的形式寫入文本 ran.write(em2.getName().getBytes()); ran.writeInt(em2.getAge()); ran.write(em3.getName().getBytes()); ran.writeInt(em3.getAge()); * * */ /* *了解了上麵因為漢字而出的弊端後,我們修改如下(一種方法): * * 為了達到每條記錄等長的效果,我們可以將實體em1、em2、em3中的20個字節設法全部輸出 * * 注意: * writeChars函數按字符序列將一個字符串寫入該文件,其中每個字符按雙字節值將 char 寫入該文件,先寫高字節 * readchar函數從文件中讀取一個 Unicode 字符。此方法從該文件的當前文件指針開始讀取兩個字節 * * */ ran.writeChars(em1.getName()); ran.writeInt(em1.getAge()); ran.writeChars(em1.getName()); ran.writeInt(em1.getAge()); ran.writeChars(em2.getName()); ran.writeInt(em2.getAge()); ran.writeChars(em3.getName()); ran.writeInt(em3.getAge()); ran.close(); //測試隨機讀取 //int len = 0; //byte[] buf = new byte[8]; //int age = 0; String name =""; RandomAccessFile ranr = new RandomAccessFile("random2.txt","r"); //先讀第二個記錄 ranr.skipBytes(Employee.LEN*2+4);//先跳過12個字節 //len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 //name = new String(buf,0,len);//將buf數組寫入name字符流 for(int i = 0 ; i < Employee.LEN;i++){ name += ranr.readChar(); } System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 //在讀第一個記錄 ranr.seek(0);//絕對定位到0上 //len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 //name = new String(buf,0,len);//將buf數組寫入name字符流 name = ""; for(int i=0 ; i < Employee.LEN ; i++){ name += ranr.readChar(); } System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 //最後讀第三個記錄 ranr.skipBytes(Employee.LEN*2+4);//再跳過12個字節 //len = ranr.read(buf);//讀取buf.length個字節 讀取到buf數組 //name = new String(buf,0,len);//將buf數組寫入name字符流 name = "" ; for(int i = 0 ; i < Employee.LEN ; i++){ name += ranr.readChar(); } System.out.println(name.trim() +":"+ranr.readInt());//將名字與後麵讀取的int四個字節合並 輸出 ranr.close(); } }
最後更新:2017-04-02 22:16:31