java編程思想讀書筆記 第十八章 java I/O系統(第一篇)

1. File類
File(文件)類這個名字有一定的誤導性;我們可能會認爲它指代的是文件,實際上卻並非如此。塔既能代表一個特定文件的名稱,又能代表一個目錄下的一組文件的名稱。如果它指的是一個文件集,我們就可以對此集合調用list()方法,這個方法會返回一個字符數組。我們很容易就可以理解返回的是一個數組而不是某個更具靈活性的容器,因爲元素的個數是固定的,所以如果想取得不同的目錄列表,只需要再創建一個不同發File對象就可以了。實際上FilePath(文件路徑)對這個類來說是個更好的名字。

1.1目錄列表器
查看一個目錄列表,可以用兩種方法來使用File對象,一是調用不帶參數的list()方法,便可以獲得此File對象包含的全部列表;另外一個是獲得一個受限列表就要通過”目錄過濾器“纔可以了。

1.2 目錄實用工具
程序中一項常見的任務就是在文件集上執行操作,這些文件要麼在本地目錄中,要麼遍佈於整個目錄樹種。如果有一種工具能夠爲你產生這個文件集,那麼它會非常有用。下面的實用工具類就可以通過使用local()方法產生的本地目錄中的文件構成的File對象數組,或者通過使用walk()方法產生給定目錄下的由整個目錄樹種所有文件構成的List。例子如下:

public final class Directory {
    public static File[] local(File dir,final String regex){
        return dir.listFiles(new FilenameFilter() {
            private Pattern pattern = Pattern.compile(regex);
            @Override
            public boolean accept(File dir, String name) {
                return pattern.matcher(new File(name).getName()).matches();
            }
        });
    }
    public static File[] local(String path,final String regex){
        return local(new File(path), regex);
    }
    public static class TreeInfo implements Iterable<File>{

        public List<File> files = new ArrayList<File>();
        public List<File> dirs = new ArrayList<File>();
        @Override
        public Iterator<File> iterator() {
            return files.iterator();
        }
        void addAll(TreeInfo other){
            files.addAll(other.files);
            dirs.addAll(other.dirs);
        }
        public String toString(){
            return "dirs:";
        }
    }
    public static TreeInfo walk(String start,String regex){
        return recurseDirs(new File(start), regex);
    }
    public static TreeInfo walk(File start,String regex){
        return recurseDirs(start, regex);
    }
    public static TreeInfo walk(File start){
        return recurseDirs(start, ".*");
    }
    public static TreeInfo walk(String start){
        return recurseDirs(new File(start), ".*");
    }
    public static TreeInfo recurseDirs(File startDir,String regex){
        TreeInfo result = new TreeInfo();
        for (File file : startDir.listFiles()) {
            if (file.isDirectory()) {
                result.dirs.add(file);
                result.addAll(recurseDirs(file, regex));
            }else {
                if (file.getName().matches(regex)) {
                    result.files.add(file);
                }
            }
        }
        return result;
    }
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println(walk("."));
        }else {
            for (String string : args) {
                System.err.println(walk(string));
            }
        }
    }
}

local()方法使用被稱爲listFile()的File.list()的辯題來產生File數組。可以看到,還使用了FilenameFilter。如果需要List而不是數組,你可以使用Arrays.asList()對結果進行轉換。

1.3 目錄的檢查及創建
File對不僅僅只代表存在的文件或目錄。也可以用File對象來創建新的目錄或尚不存在的整個目錄的路徑。還可以查看文件的特性(如:大小,最後修改日期等),檢查某個File對象代表的是一個文件還是一個目錄,並可以刪除文件。文件操作包括以下幾個方法:
f.isFile()判斷是否是一個文件
f.isDirectory()判斷是一個文件目錄
file.exists()判斷文件是否存在
file.delete()刪除文件
file.mkdirs()創建文件
file.getAbsolutePath()獲取文件的絕對路徑
file.getName()獲取文件的名字

2. 輸入和輸出
流是個抽象的概念,它代表任何有能力產出數據的數據源對象或者是具有能力接收數據的接收端對象。“流”屏蔽了實際的I/O設備中處理數據的細節。
java類庫中的I/O類分成輸入和輸出部分,通過繼承,任何自InputStream或Reader派生而來的類都含有名爲read()的基本方法,用於讀取單個字節或者字節數組。同樣,任何自OutputStream或Writer派生而來的類都含有名爲write()的基本方法,用於寫單個字節或者字節數組。但是我們通常不會用到這些方法,她們之所以存在是因爲別的類可以使用它們,以便提供更有用的接口。因此,創建流的對象是通過疊合多個對象來提供所期望的功能。實際上,java中“流”類庫讓人迷惑的主要原因在於:創建單一的流卻需要創建多個對象。

2.1 InputStream類型
InputStream作用是用來表示那些從不同數據源產生輸入的類。這些數據源包括:
1)字節數組
2)String對象
3)文件
4)“管道”,工作方式與實際管道相似,即從一端輸入,從另一端輸出。
5)一個由其他種類的流組成的序列,以便我們可以將他們收集合併到一個流內。
6)其他數據源
每一種數據源都有相應的InputStream子類。另外FilterInputStream也屬於InputStream。下圖是InputStream類型:

這裏寫圖片描述

2.2 OutputStream類型
如下圖所示,該類別的類決定了輸出所要去往的目標:字節數組(但部署String,不過你當然可以用字節數組字自己創建)、文件或管道。

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章