1. 程式人生 > >圖解 Java IO : 一、File原始碼

圖解 Java IO : 一、File原始碼

Writer      :李強強

記得Java原始碼是從集合類開始看的,寫了一系列集合相關的文章,受到不錯的評價。感謝各位讀者。我依舊會讀到老寫到老,並生動形象的寫出來心得體會。這次依舊是圖解Java IO。

Java IO – File的要點,應該是

1、跨平臺問題的解決

2、檔案的安全

3、檔案的檢索方法

一、程式碼小引入

代請看一個簡單的小demo:(ps:開源專案java-core-learning地址https://github.com/JeffLi1993

import java.io.File;
import java.util.Arrays;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-13 07:58:56
 * 列出目錄並排序
 */
public class DirListT {
	public static void main(String[] args) {
		// 獲取當前目錄
		File path = new File(".");// .表示當前目錄
		// 檔案路徑名陣列
		String list[] = path.list();
		
		// 對String檔名進行排序
		Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);
		
		// 列印
		for(String dirItem : list)
			System.out.println(dirItem);
	}
}

在eclipse中,右鍵run一下,可以得到如下的結果:

image

如圖,很容易注意到了,其目錄下的名字排序按字母並列印了。

先回顧下API知識吧,

首先建構函式 public File(String pathname)

通過將給定路徑名字串轉換為抽象路徑名來建立一個新 File 例項。如果給定字串是空字串,那麼結果是空抽象路徑名。

引數:
pathname – 路徑名字串
丟擲:
二者,File實現了Comparator介面,以便對FileName進行排序



          一個對 String 物件進行排序的 Comparator,作用與 compareToIgnoreCase

相同。

三者, path.list()為什麼會返回String[] filenams的陣列呢?怎麼不是List呢?

自問自答:這時候,我們應該去看看ArrayList的實現,ArrayList其實是動態的陣列實現。動態,動態的弊端就是效率低。此時,返回一個固定的陣列,而不是一個靈活的類容器,因為其目錄元素是固定的。下面是ArrayList和陣列Array的比較

繪圖1

二、深入理解原始碼

File,File究竟是怎麼構成的。順著原始碼,知道了File有幾個重要屬性

clipboard

1、static private FileSystem fs

     FileSystem : 對本地檔案系統的抽象

2、String path 檔案路徑名

3、內聯列舉類

     PathStatus 地址是否合法 ENUM類 private static enum PathStatus { INVALID, CHECKED };

4、prefixLength 字首長度

如下,給出File相關核心的UML圖
file

其實操作的是 FileSystem : 對本地檔案系統的抽象,真正操作的是 FileSytem派生類。通過原始碼Ctrl+T發現如下:Win下操作的是 Win32FileSystemWinNTFileSystem類。看來真正通過jvm,native呼叫系統的File是他們。

clipboard[1]

Linux呢?因此,下了個Linux版本的JDK,解壓,找到rt.jar。然後java/io目錄中,找到了UnixFileSystem類。真相大白了!

clipboard[2]

所以可以小結File操作原始碼這樣呼叫的:中間不同JDK,其實是不同的類呼叫本機native方法

繪圖1

三、小demo再來一發

File 其實和我們在系統中看的的檔案一樣。就像我們右鍵,屬性。可以看到很多File的資訊。Java File也有。下面是一個檔案的相關方法詳情:

import java.io.File;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Jeff Lee
 * @since 2015-7-13 10:06:28
 * File方法詳細使用
 */
public class FileMethodsT {
	
	private static void fileData(File f) {
		System.out.println(
			" 絕對路徑:" + f.getAbsolutePath() +
			"\n 可讀:" + f.canRead() +
			"\n 可寫:" + f.canWrite() +
			"\n 檔名:" + f.getName() +
			"\n 上級目錄:" + f.getParent() +
			"\n 相對地址:" + f.getPath() +
			"\n 長度:" + f.length() +
			"\n 最近修改時間:" + f.lastModified()
			);
		if(f.isFile())
			System.out.println(" 是一個檔案");
		else if(f.isDirectory())
			System.out.println(" 是一個目錄");
	}
	
	public static void main(String[] args) {
		// 獲取src目錄
		File file = new File("src");
		// file詳細操作
		fileData(file);
	}
}

在eclipse中,右鍵run一下,可以得到如下的結果:大家應該都明白了吧。

image

檔案如何過濾呢?

以後獨立講吧,過濾涉及Fiter類。

四、總結

1、看原始碼很簡單,看資料結構。看如何呼叫。或者是有些設計模式

2、學東西,學一點一點深一點。太深不好,一點就夠了

3、泥瓦匠學習的程式碼都在github上(同步osc git),歡迎大家點star,提意見,一起進步。地址:https://github.com/JeffLi1993

Writer      :BYSocket(泥沙磚瓦漿木匠)