在真正學習Java I/O之前,我們先了解一個實用的操作目錄及文件的類-File類
1、File類
File類不僅僅只代表存在的目錄或者文件。也可以用 File 對象來創建新的文件或者尚不存在的目錄路徑;查看文件的特性(大小、最後修改日期、讀/寫);判斷某一個file對象是目錄還是文件;刪除文件等操作。
1.1、構造方法
- new File(Sting filePath) 通過給定的路徑來創建一個File實例
- new File(String parent , String child) parent是上級目錄的路徑,完整的路徑爲 parent+child
- new File(File parentFile , String child) 完整的路徑爲parent.getPath()+child
文件路徑中的分隔符:Windows中的分隔符爲’\’,在Unix/Linux中分隔符是’/’。更正確的做法是使用FIle.separatorChar來獲取當前系統相應的分隔符。
1.2、File類中常用的方法
1.2.1、創建
- boolean createNewFIle() 在指定位置創建一個空文件,成功返回true,如果文件已經存在則不創建文件並返回false。
- boolean mkdir() 在指定位置創建目錄,該方法只會創建最後一級目錄,如果上級目錄不存在就會拋出異常。
- boolean mkdirs() 指定位置創建目錄,可以是多層目錄。
- boolean renameTo(file desc) 重命名文件或者文件夾,可以操作非空文件夾,相當於文件的剪切。
1.2.2、刪除
- boolean delete() 刪除文件或者一個空文件夾,如果文件夾不爲空就不能刪除並返回false。
- boolean deleteOnExit() 虛擬機終止時,請求刪除此路徑下的文件或目錄,保證程序異常退出時的臨時文件被刪除。
1.2.3、判斷
- boolean exists() 文件或者文件夾是否存在。
- boolean isFile() 是否爲一個文件,如果不存在則返回false。
- boolean isDirectory() 是否爲一個目錄,如果不存在則返回false。
- boolean isHidden() 是否是一個隱藏的文件或者目錄。
- boolean isAbsolute() 判斷該文件路徑是否爲絕對路徑。
1.2.4、獲取
- String getName() 獲取當前文件或者文件夾的名稱,不包括上級路徑。
- String getPath() 返回文件路徑。
- String getAbsolutePath() 返回文件的絕對路徑,與文件是否存在無關.
- long length() 返回文件的字節數大小,如果文件不存在則返回0L,如果是文件夾也返回0L。
- long lastModified() 獲取最後一次被修改的時間。
- static file[] listRoots() 返回根目錄,Windows中就是所有的盤符,Linux系統返回’/’。
- String list() 返回目錄下的文件或者文件夾,包含隱藏文件。
- String list(FilenameFilter filter) 返回當前目錄中符合過濾條件的子文件或者子目錄。
- File[] listFiles() 返回目錄下的文件或者目錄對象。
- File[] listFiles(FilenameFilter filter) 返回當前目錄中符合過濾條件的子文件或子目錄。
1.3、FilenameFilter的使用
假設我們需要遍歷一個目錄列表,可以使用兩種方法來使用File對象。一種是不帶參數的listFiles()方法,可以獲得此file對象包含的全部列表。然而,有時我們需要獲得一個受限的列表。假如,想要獲取所有以 .java 結尾的文件,那麼最好的方法是使用FilenameFilter。
FilenameFilter是一個接口,需要我們在代碼中實現accept()方法的邏輯處理:
@FunctionalInterface
public interface FilenameFilter {
/**
* Tests if a specified file should be included in a file list.
*
* @param dir the directory in which the file was found.
* @param name the name of the file.
* @return <code>true</code> if and only if the name should be
* included in the file list; <code>false</code> otherwise.
*/
boolean accept(File dir, String name);
}
獲得所有以 .java 結尾的文件對象:
package com.xiaopeng.file;
import java.io.File;
import java.io.FilenameFilter;
/**
* FilenameFilter
* 列出目錄下所有已.java爲後綴的文件對象
*/
public class MyFile {
public static void main(String[] args){
File file = new File("../JavaSE_Project/src/com/xiaopeng/file");
listJava(file);
}
private static void listJava(File file) {
File[] files = file.listFiles(new MyFilenameFilter()); //使用FilenameFilter
for(File f : files){
System.out.println(f.getName());
}
}
}
class MyFilenameFilter implements FilenameFilter{
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
我們在MyFilenameFilter中的accept方法裏判斷文件名是以 .java 結束時該方法返回true,否則返回false。查看File[] listFiles(FilenameFilter filter)會發現:
public File[] listFiles(FilenameFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
for (String s : ss)
if ((filter == null) || filter.accept(this, s)) //針對每個對象都會調用accept方法。
files.add(new File(s, this));
return files.toArray(new File[files.size()]);
}
針對目錄下的所有文件,每次遍歷都會調用accept()方法判斷該文件是否以 .java 結尾,若是則將該文件加入集合中。
FilenameFilter的實現方式實際是一種“策略模式”的使用,listFiles()方法實現了基本的功能,並且按照FilenameFilter的形式提供了一種策略。listFiles()方法接收FilenameFilter對象作爲參數,這意味着可以傳遞實現FilenameFilter接口的任何對象(即就是不同的策略)爲listFiles()方法服務,進而改變listFiles()輸出的結果。策略模式的目的就是提供代碼行爲的靈活性。