1. 程式人生 > >IO流的學習—File類

IO流的學習—File類

1.IO流的學習

在java的大部分學習,基本都是把資料儲存到記憶體當中,當結束了程序,這些資料都沒有了。但是可以通過IO流,把記憶體的資料,儲存在持久化裝置上,比如U盤,磁碟等。
* A:IO技術概述
        * a: Output
            * 把記憶體中的資料儲存到持久化裝置上這個動作稱為輸出(寫)Output操作
        * b: Input
            * 把持久裝置上的資料讀取到記憶體中的這個動作稱為輸入(讀)Input操作
        * c: IO操作
            * 把上面的這種輸入和輸出動作稱為IO操作


2.FILE類

在java的api中有一個file類,主要是對檔案操作的類,他是與平臺無關的,比如Linux系統下是/來做資料夾分割的,而window下是用\來做分割的。而用了file這個類是沒有這個煩惱的。
檔案:file
目錄:directory
路徑:path

3.API:獲取分隔符

以下方法是為了獲取在不同的情況下,獲取不同的分隔符。在window下環境變數都是使用“;”分割的。資料夾分隔符也是“\”。所以在以後的開發中,最好使用這種辦法,獲取系統的分割標準。也正是遵守了java的跨平臺性。 獲取分隔符或者分割號的時候,分別有2個方法,一個是獲取char型別,一個是獲取String型別,除此之外沒有其他的區別,但是記住,是先char型別的,因為考慮到String比較常用,所以又轉換成了String型別。
public static void main(String[] args) {
		//File類靜態成員變數
		//與系統有關的路徑分隔符
		String separator = File.pathSeparator;
		System.out.println(separator);// 是一個分號,目錄的分割   Linux :
		
		//與系統有關的預設名稱分隔符
		separator = File.separator;
		System.out.println(separator);// 向右 \  目錄名稱分割  Linux / 
	}

4.API:構造


File類有4個構造的方法,這裡先講其中一種。
File(String pathname) 
          通過將給定路徑名字串轉換為抽象路徑名來建立一個新 File 例項。
注意:
1.這個構造主要是來建立一個file類的例項,至於這個pathname的路徑是否存在,不會影響例項。
2.在寫路徑的時候一般是“//”兩個斜槓,第一個斜槓是為了轉義,這樣兩個斜槓就是一個“/”了 3.在window下檔名字都是不區別大小寫的,可以隨意命名。但是Linux下是區分大小寫的。所以在編寫程式的時候,為了考慮到跨平臺性,也要把這點給考慮進去。
	/*
	 *  File(String pathname)
	 *  傳遞路徑名: 可以寫到資料夾,可以寫到一個檔案
	 *  c:\\abc   c:\\abc\\Demo.java
	 *  將路徑封裝File型別物件
	 */
	public static void function(){
		File file = new File("d:\\eclipse");
		System.out.println(file);
	}

5.相對路徑和絕對路徑

	* A: 相對路徑和絕對路徑
		* a: 絕對路徑
			* 絕對路徑是一個固定的路徑,從碟符開始
		* b: 相對路徑
			* 相對路徑相對於某個位置,在eclipse下是指當前專案下	
		* c: 路徑
				絕對路徑
					在系統中具有唯一性
					c:\\windows\\system32
				相對路徑
					表示路徑之間的關係
					D:\\develop\\Java\\jdk1.7.0_72\\bin
					D:\\develop\\Java\\jre7
					路徑之間關係
						Java 父目錄是D:\\develop
						Java 子目錄是:jdk1.7.0_72
					父路徑是 唯一性
					子目錄是可以多個

6.API:三大構造

FILE類有3個構造,但是各不相同。以下是各個構造的詳解。
File(File parent, String child) 
          根據 parent 抽象路徑名和 child 路徑名字串建立一個新 File 例項。 
File(String pathname) 
          通過將給定路徑名字串轉換為抽象路徑名來建立一個新 File 例項。 
File(String parent, String child) 
          根據 parent 路徑名字串和 child 路徑名字串建立一個新 File 例項。 

其中的File(String pathname)的構造已經在上面講過了。

這裡主要說明另外兩種,File(File parent,String child) 和 File(String parent,String child)。其中這兩個非常相似,不同的是引數的父目錄不相同。

直接使用file類的例項,一種是String型別。這樣的構造介面也是為了方便。 可以通過引數,直接定義子路徑。
	/*
			 *  File(File parent,String child)
			 *  傳遞路徑,傳遞File型別父路徑,字串子路徑
			 *  好處: 父路徑是File型別,父路徑可以直接呼叫File類方法
			 */
			public static void function_2(){
				File parent = new File("d:");
				File file = new File(parent,"eclipse");
				System.out.println(file);
			}
			
			/*
			 *  File(String parent,String child)
			 *  傳遞路徑,傳遞字串父路徑,字串子路徑
			 *  好處: 單獨操作父路徑和子路徑
			 */
			public static void function_1(){
				File file = new File("d:","eclipse");
				System.out.println(file);
			}


7.API:建立檔案

createNewFile()只能建立檔案,不能建立資料夾。會返回一個布林值。
createNewFile
public boolean createNewFile()
                      throws IOException當且僅當不存在具有此抽象路徑名指定名稱的檔案時,不可分地建立一個新的空檔案。檢查檔案是否存在,若不存在則建立該檔案,這是單個操作,對於其他所有可能影響該檔案的檔案系統活動來說,該操作是不可分的。 
注:此方法不應該 用於檔案鎖定,因為所得協議可能無法可靠地工作。應該使用 FileLock 機制替代。 


返回:
如果指定的檔案不存在併成功地建立,則返回 true;如果指定的檔案已經存在,則返回 false 
丟擲: 
IOException - 如果發生 I/O 錯誤 
SecurityException - 如果存在安全管理器,且其 SecurityManager.checkWrite(java.lang.String) 方法拒絕對檔案進行寫訪問
從以下版本開始: 
1.2 


示例:
	/*
	 *  File建立檔案的功能
	 *  boolean createNewFile()
	 *  建立的檔案路徑和檔名,在File構造方法中給出
	 *  檔案已經存在了,不在建立
	 */
	public static void function()throws IOException{
		File file = new File("c:\\a.txt");
		boolean b = file.createNewFile();
		System.out.println(b);
	}


8.API:建立資料夾

api提供了兩個方法來建立資料夾, mkdir()。只能建立一層資料夾。 mkdirs()。可以建立多層資料夾。也可以建立單層資料夾。所以在使用的時候,更多的是使用mkdirs()。
/*
	 *  File建立資料夾功能
	 *  boolean mkdirs() 建立多層資料夾
	 *  建立的路徑也在File構造方法中給出
	 *  資料夾已經存在了,不在建立
	 */
	public static void function_1(){
		File file = new File("c:\\abc");
		boolean b = file.mkdirs();
		System.out.println(b);
	}

9.API:刪除

	/*
	 *  File類的刪除功能
	 *  boolean delete()
	 *  刪除的檔案或者是資料夾,在File構造方法中給出
	 *  刪除成功返回true,刪除失敗返回false
	 *  刪除方法,不走回收站,直接從硬碟中刪除
	 *  刪除有風險,執行需謹慎
	 */
	public static void function_2(){
		File file = new File("c:\\a.txt");
		boolean b = file.delete();
		System.out.println(b);
	}

10.API:獲取功能

獲取檔名字:相當於字串功能。取得路徑的最後一個字串。
	/*
	 *  File類的獲取功能
	 *  String getName()
	 *  返回路徑中表示的檔案或者資料夾名
	 *  獲取路徑中的最後部分的名字
	 */
	public static void function(){
		File file = new File("d:\\eclipse\\eclipse.exe");
		String name = file.getName();
		System.out.println(name);
		
		/*String path = file.getPath();
		System.out.println(path);*/
//		System.out.println(file);
	}
獲取檔案位元組數的功能:獲取檔案大小。
	/*
	 * File類獲取功能
	 * long length()
	 * 返回路徑中表示的檔案的位元組數
	 */
	public static void function_1(){
		File file = new File("d:\\eclipse\\eclipse.exe");
		long length = file.length();
		System.out.println(length);
	}
獲取檔案的絕對路徑:檔案路徑的父目錄都是在eclipse的專案目錄下。
	/*
	 * File類獲取功能
	 * String getAbsolutePath() 返回String物件
	 * File   getAbsoluteFile() 返回File物件
	 * 獲取絕對路徑
	 * eclipse環境中,寫的是一個相對路徑,絕對位置工程根目錄
	 */
	public static void function_2(){
		File file = new File("src");
		File absolute = file.getAbsoluteFile();
		System.out.println(absolute);
	}
獲取檔案的父目錄:這裡要注意的是C:/的父目錄的是null。如果在去獲取父目錄,就是空指標了。
	/*
	 * File類的獲取功能
	 * String getParent() 返回String物件
	 * File getParentFile()返回File物件
	 * 獲取父路徑
	 */
	public static void function_3(){
		File file = new File("d:\\eclipse\\eclipse.exe");
		File parent = file.getParentFile();
		System.out.println(parent);
	}


11.API:判斷功能

判斷路徑是否存在。
	/*
	 *  File判斷功能
	 *  boolean exists()
	 *  判斷File構造方法中封裝路徑是否存在
	 *  存在返回true,不存在返回false
	 */
	public static void function(){
		File file = new File("src");
		boolean b = file.exists();
		System.out.println(b);
	}
其中isDirectory()判斷資料夾,isFile()判斷檔案。 正常邏輯是,判斷路徑是否存在,再判斷是否為檔案或資料夾
	/*
	 *  File判斷功能
	 *  boolean isDirectory()
	 *  判斷File構造方法中封裝的路徑是不是資料夾
	 *  如果是資料夾,返回true,不是檔案返回false
	 *  
	 *  boolean isFile()
	 *  判斷File構造方法中封裝的路徑是不是檔案
	 */
	public static void function_1(){
		File file = new File("d:\\eclipse\\eclipse.exe");
		if(file.exists()){
			boolean b = file.isDirectory();
			System.out.println(b);
		}
	}


12.API:獲取目錄檔名

listFiles()和File()方法,要知道這兩個方法,能夠獲取系統下隱藏的檔案或資料夾。
區別: 1.listFiles()返回的是file陣列。File()返回的是String陣列。 2.listFiles()返回的資料,是全路徑。而File()返回的是名字。
				/*
				 *  File類的獲取功能
				 *  File[] listFiles()
				 *  獲取到,File構造方法中封裝的路徑中的檔案和資料夾名 (遍歷一個目錄)
				 *  返回的是目錄或者檔案的全路徑
				 */
				public static void function_1(){
					File file = new File("d:\\eclipse");
					File[] fileArr = file.listFiles();
					for(File f : fileArr){
						System.out.println(f);
					}
				}
				
				/*
				 *  File類的獲取功能
				 *  String[] list()
				 *  獲取到,File構造方法中封裝的路徑中的檔案和資料夾名 (遍歷一個目錄)
				 *  返回只有名字
				 */
				public static void function(){
					File file = new File("c:");
					String[] strArr = file.list();
					System.out.println(strArr.length);
					for(String str : strArr){
						System.out.println(str);
					}
				}


擴充套件: 靜態方法listRoots()。獲取系統中的所有根目錄。
				public static void function_2(){
					//獲取系統中的所有根目錄
					File[] fileArr = File.listRoots();
					for(File f : fileArr){
						System.out.println(f);
					}
				}


13.API:檔案過濾器

listFiles(FileFilter filter)介面型別這個方法,他的引數FileFilter是一個介面,需要建立他的實現類,實現類裡有accept的方法。當呼叫到listFiles的時候,就會呼叫到accept這個方法,再accept裡去對檔案型別進行判斷,如果為false就過濾掉。
該方法只能獲取當前目錄,不是全目錄。
			/*
			 *  自定義過濾器
			 *  實現FileFilter介面,重寫抽象方法
			 */
			public class MyFilter implements FileFilter{
				public boolean accept(File pathname)  {
					/*
					 * pathname 接受到的也是檔案的全路徑
					 * c:\\demo\\1.txt
					 * 對路徑進行判斷,如果是java檔案,返回true,不是java檔案,返回false
					 * 檔案的字尾結尾是.java
					 */
					//String name = pathname.getName();
					return pathname.getName().endsWith(".java");
					
				}
			}
			
			/*
			 *  File類的獲取,檔案獲取過濾器
			 *  遍歷目錄的時候,可以根據需要,只獲取滿足條件的檔案
			 *  遍歷目錄方法 listFiles()過載形式
			 *  listFiles(FileFilter filter)介面型別
			 *  傳遞FileFilter介面的實現類
			 *  自定義FileFilter介面實現類,重寫抽象方法,
			 *  介面實現類物件傳遞到遍歷方法listFiles
			 */
			public class FileDemo1 {
				public static void main(String[] args) {
					File file = new File("c:\\demo");
					File[] fileArr = file.listFiles(new MyFilter());
					for(File f : fileArr){
						System.out.println(f);
					}
				}
			}


原理
檔案過濾器_原理分析
	* A:檔案過濾器_原理分析
		* listFiles()遍歷目錄的同時,獲取到了檔名全路徑,呼叫過濾器的方法accept,將獲取到的路徑傳遞給accept方法的引數pathname
		* accept方法接收了引數pathname,引數是listFiles傳遞來的
		* 在accept方法中,進行判斷,如果這個路徑是Java檔案,返回true,走著返回false
		* 一旦方法返回了true
		* listFiles將路徑儲存到File陣列中



14.遍歷全目錄

這個方法主要是利用了遞迴呼叫,遍歷出了全部的檔案。 這裡所讀取的路徑一定要是資料夾,不能是根目錄,如果是根目錄返回值會是null,null之後在讀取會空指標。
				/*
				 *  定義方法,實現目錄的全遍歷
				 */
				public static void getAllDir(File dir){
					System.out.println(dir);
					//呼叫方法listFiles()對目錄,dir進行遍歷
					File[] fileArr = dir.listFiles();
					for(File f : fileArr){
						//判斷變數f表示的路徑是不是資料夾
						if(f.isDirectory()){
							//是一個目錄,就要去遍歷這個目錄
							//本方法,getAllDir,就是給個目錄去遍歷
							//繼續呼叫getAllDir,傳遞他目錄
							getAllDir(f);
						}else{
							System.out.println(f);
						}
					}
				}


15.遍歷目錄下的所有java檔案

過濾器要加上資料夾判斷, toLowerCase()是把字母改成小寫,在windows上不分大小寫。
public class MyJavaFilter implements FileFilter {
				public boolean accept(File pathname) {
					//判斷獲取的是目錄,直接返回true
					if(pathname.isDirectory())
						return true;
					return pathname.getName().toLowerCase().endsWith(".java");
				}

			}
			/*
			 *  遍歷目錄,獲取目錄下的所有.java檔案
			 *  遍歷多級目錄,方法遞迴實現
			 *  遍歷的過程中,使用過濾器
			 */
			public class FileDemo1 {
				public static void main(String[] args) {
					getAllJava(new File("c:\\demo"));
			//		new File("c:\\demo").delete();
				}
				/*
				 * 定義方法,實現遍歷指定目錄
				 * 獲取目錄中所有的.java檔案
				 */
				public static void getAllJava(File dir){
					//呼叫File物件方法listFiles()獲取,加入過濾器
					File[] fileArr = dir.listFiles(new MyJavaFilter());
					for(File f : fileArr){
						//對f路徑,判斷是不是資料夾
						if(f.isDirectory()){
							//遞迴進入資料夾遍歷
							getAllJava(f);
						}else{
							System.out.println(f);
						}
					}
				}
			}