隨機(jī)訪問文件
文件操作
java.io 定義的大多數(shù)類都是流式操作吃环,但 File 類不是。它直接處理文件和文件系統(tǒng)洋幻。File 類沒有指定信息怎樣從文件讀取或向文件存儲(chǔ)郁轻;它描述了文件本身的屬性。File 對(duì)象用來獲取或處理與磁盤文件相關(guān)的信息文留,例如權(quán)限好唯,時(shí)間,日期和目錄路徑厂庇。此外渠啊,F(xiàn)ile 還瀏覽子目錄層次結(jié)構(gòu)。Java 中的目錄當(dāng)成 File 對(duì)待权旷,它具有附加的屬性——一個(gè)可以被 list( ) 方法檢測(cè)的文件名列表替蛉。
先看一看 File 的構(gòu)造方法:
//根據(jù) parent 抽象路徑名和 child 路徑名字符串創(chuàng)建一個(gè)新 File 實(shí)例。
File(File parent, String child)
//通過將給定路徑名字符串轉(zhuǎn)換為抽象路徑名來創(chuàng)建一個(gè)新 File 實(shí)例
File(String pathname)
// 根據(jù) parent 路徑名字符串和 child 路徑名字符串創(chuàng)建一個(gè)新 File 實(shí)例
File(String parent, String child)
//通過將給定的 file: URI 轉(zhuǎn)換為一個(gè)抽象路徑名來創(chuàng)建一個(gè)新的 File 實(shí)例
File(URI uri)
例如:
//一個(gè)目錄路徑參數(shù)
File f1 = new File("/Users/mumutongxue/");
//對(duì)象有兩個(gè)參數(shù)——路徑和文件名
File f2 = new File("/Users/mumutongxue/","a.bat");
//指向 f1 文件的路徑及文件名
File f3 = new File(f1,"a.bat");
再來看看File的一些方法
方法 | 說明 |
---|---|
boolean canExecute() | 測(cè)試應(yīng)用程序是否可以執(zhí)行此抽象路徑名表示的文件 |
boolean canRead() | 測(cè)試應(yīng)用程序是否可以讀取此抽象路徑名表示的文件 |
boolean canWrite() | 測(cè)試應(yīng)用程序是否可以修改此抽象路徑名表示的文件 |
int compareTo(File pathname) | 按字母順序比較兩個(gè)抽象路徑名 |
boolean createNewFile() | 當(dāng)且僅當(dāng)不存在具有抽象路徑名指定名稱的文件時(shí)拄氯,不可分地創(chuàng)建一個(gè)新的空文件 |
static File createTempFile(String prefix, String suffix, File directory) | 在指定目錄中創(chuàng)建一個(gè)新的空文件躲查,使用給定的前綴和后綴字符串生成其名稱 |
static File createTempFile(String prefix, String suffix, File idrectory) | 在指定目錄中創(chuàng)建一個(gè)新的空文件,使用給定的前綴和后綴字符串生成其名稱 |
boolean delete() | 刪除此抽象路徑名表示的文件或目錄 |
void deleteOnExit() | 在虛擬機(jī)終止時(shí)译柏,請(qǐng)求刪除此抽象路徑名表示的文件或目錄 |
boolean equals(Object obj) | 測(cè)試此抽象路徑名與給定對(duì)象是否相等 |
boolean exists() | 測(cè)試此抽象路徑名表示的文件或目錄是否存在 |
File getAbsoluteFile() | 返回此抽象路徑名的絕對(duì)路徑名形式 |
String getAbsolutePath() | 返回此抽象路徑名的絕對(duì)路徑名字符串 |
File getCanonicalFile() | 返回此抽象路徑名的規(guī)范形式 |
String getCanonicalPath() | 返回此抽象路徑名的規(guī)范名字符串 |
long getFreeSpace() | 返回此抽象路徑名指定的分區(qū)中為分配的字節(jié)數(shù) |
String getName() | 返回由此抽象路徑名表示的文件或目錄的名稱 |
String getParent() | 返回此抽象路徑名父目錄的路徑字符串镣煮;如果此路徑名沒有指定父目錄,則返回 null |
File getParentFile() | 返回此抽象路徑名父目錄的抽象路徑名鄙麦;如果此路徑名沒有指定父目錄典唇,則返回null |
String getPath() | 將此抽象路徑名轉(zhuǎn)換為一個(gè)路徑名字符串 |
long getTotalSpace() | 返回此抽象路徑名指定的分區(qū)大小 |
long getUsableSpace() | 返回此抽象路徑名指定的分區(qū)上可用于此虛擬機(jī)的字節(jié)數(shù) |
int hashCode() | 計(jì)算此抽象路徑名的哈希碼 |
boolean isAbsolute() | 測(cè)試此抽象路徑名是否為絕對(duì)路徑名 |
boolean isDirectory() | 測(cè)試此抽象路徑名表示的文件是否一個(gè)目錄 |
boolean isFile() | 測(cè)試此抽象路徑名表示的文件是否是一個(gè)標(biāo)準(zhǔn)文件 |
boolean isHidden() | 測(cè)試此抽象路徑名指定的文件是否是一個(gè)隱藏文件 |
long lastModified() | 返回此抽象路徑名表示的文件最后一次被修改的時(shí)間 |
long length() | 返回由此抽象路徑名表示的文件最后一次被修改的時(shí)間 |
String[] list() | 返回一個(gè)字符串?dāng)?shù)組镊折,這些字符串指定此抽象路徑名表示的目錄中的文件和目錄 |
String[] list(FilenameFilter filter) | 返回一個(gè)字符串?dāng)?shù)組,這些字符串指定此抽象路徑名表示的目錄中滿足指定過濾器的文件和目錄 |
File[] listFiles() | 返回一個(gè)抽象路徑名數(shù)組介衔,這些路徑名表示此抽象路徑名表示的目錄中的文件 |
File[] listFiles(FileFiter filter) | 返回抽象路徑名數(shù)組恨胚,這是路徑名表示此抽象路徑名表示的目錄中滿足指定過濾器的文件和目錄 |
File[] listFiles(FilenameFilter filter) | 返回抽象路徑名數(shù)組, 這些路徑名表示此抽象路徑名表示的 目錄中滿足指定過濾器的文件和目錄 |
static File[] listRoots() | 列出可用的文件系統(tǒng)根 |
boolean mkdir() | 創(chuàng)建此抽象路徑名指定的目錄 |
boolean mkdirs() | 創(chuàng)建此抽象路徑名指定的目錄炎咖,包括所有必須但不存在的父目錄 |
boolean renameTo(File dest) | 重新命名此抽象路徑名表示的文件 |
boolean setExecutable(boolean executable) | 設(shè)置此抽象路徑名所有者執(zhí)行權(quán)限的一個(gè)便捷方法 |
boolean setExecutable(boolean executable, boolean ownerOnly) | 設(shè)置此抽象路徑名的所有者或所有用戶的執(zhí)行權(quán)限 |
boolean setLastModified(long time) | 設(shè)置此抽象路徑名指定的文件或目錄的最后一次修改時(shí)間 |
boolean setReadable(boolean readable) | 設(shè)置此抽象路徑名所有者讀權(quán)限的一個(gè)便攜方法 |
boolean setReadable(boolean readable, boolean ownerOnly) | 設(shè)置此抽象路徑名的所有者或所有用戶的讀權(quán)限 |
boolean setReadOnly() | 標(biāo)記此抽象路徑名指定的文件或目錄赃泡,從而只能對(duì)其進(jìn)行讀操作 |
boolean setWritable(boolean writable, boolean ownerOnly) | 設(shè)置此抽象路徑名的所有者或所有用戶的寫權(quán)限 |
String toString() | 返回此抽象路徑名的路徑名字符串 |
URI toURI() | 構(gòu)造一個(gè)表示此抽象路徑名的file:URI |
示例代碼
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args){
//同學(xué)們可以根據(jù)自己的路徑進(jìn)行更改
File f1 =new File("/home/project/1.txt");
//File(String parent,String child)
File f2 =new File("/home/project","2.txt");
//separator 跨平臺(tái)分隔符
File f3 =new File("/home"+File.separator+"project");
File f4 =new File(f3,"3.txt");
try {
System.out.println(f1);
//當(dāng)文件存在時(shí)返回 false;不存在時(shí)返回 true
System.out.println(f2.createNewFile());
//當(dāng)文件不存在時(shí)返回 false
System.out.println(f3.delete());
}catch(IOException e) {
e.printStackTrace();
}
//列出磁盤下的文件和文件夾
File[] files =File.listRoots();
for(File file:files){
System.out.println(file);
if(file.length()>0){
String[] filenames =file.list();
for(String filename:filenames){
System.out.println(filename);
}
}
}
}
}
隨機(jī)訪問文件
對(duì)于 FileInputStream/FileOutputStream乘盼、FileReader/FileWriter 來說升熊,它們的實(shí)例都是順序訪問流,即只能進(jìn)行順序讀/寫绸栅。而類 RandomAccessFile 則允許文件內(nèi)容同時(shí)完成讀和寫操作级野,它直接繼承 object,并且同時(shí)實(shí)現(xiàn)了接口 DataInput 和 DataOutput阴幌。
隨機(jī)訪問文件的行為類似存儲(chǔ)在文件系統(tǒng)中的一個(gè)大型 byte 數(shù)組勺阐。存在指向該隱含數(shù)組的光標(biāo)或索引,稱為文件指針矛双;輸入操作從文件指針開始讀取字節(jié),并隨著對(duì)字節(jié)的讀取而前移此文件指針蟆豫。如果隨機(jī)訪問文件以讀取/寫入模式創(chuàng)建议忽,則輸出操作也可用;輸出操作從文件指針開始寫入字節(jié)十减,并隨著對(duì)字節(jié)的寫入而前移此文件指針栈幸。
RandomAccessFile 提供了支持隨機(jī)文件操作的方法:
- readXXX() 或者 writeXXX(): 如 ReadInt(),ReadLine(),WriteChar(),WriteDouble() 等
- int skipBytes(int n): 將指針向下移動(dòng)若干字節(jié)
- length(): 返回文件長(zhǎng)度
- long getFilePointer(): 返回指針當(dāng)前位置
- void seek(long pos): 將指針調(diào)用所需位置
在生成一個(gè)隨機(jī)文件對(duì)象時(shí),除了要指定文件對(duì)象和文件名之外帮辟,還需要指明訪問文件的模式速址。
我們來看看RandomAccessFile的構(gòu)造方法:
RandomAccessFile(File file,String mode)
RandomAccessFile(String name,String mode)
mode 的取值:
- r: 只讀,任何寫操作都講拋出 IOException
- rw: 讀寫由驹,文件不存在時(shí)會(huì)創(chuàng)建該文件芍锚,文件存在是,原文件內(nèi)容不變蔓榄,通過寫操作改變文件內(nèi)容并炮。
- rws: 打開以便讀取和寫入,對(duì)于 "rw"甥郑,還要求對(duì)文件的內(nèi)容或元數(shù)據(jù)的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備逃魄。
- rwd: 打開以便讀取和寫入,對(duì)于 "rw"澜搅,還要求對(duì)文件內(nèi)容的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備伍俘。
例子:
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileDemo {
public static void main(String[] args){
int data_arr[] = {12, 32, 43, 45, 1, 5};
try {
RandomAccessFile randf=new RandomAccessFile("temp.dat","rw");
for(int i = 0; i < data_arr.length; i++){
randf.writeInt(data_arr[i]);
}
for(int i = data_arr.length-1 ; i >= 0; i--){
//int 數(shù)據(jù)占 4 個(gè)字節(jié)
randf.seek(i * 4L);
System.out.println(randf.readInt());
}
randf.close();
}catch(IOException e){
System.out.println("File access error" + e);
}
}
}