【Java基礎】——IO流(中)


一、 File 類

1、概述

①什麼是File類:用於封裝一個路徑,封裝的路徑可以是文件或文件夾。是文件和目錄路徑名的抽象表現形式。
②File類的特點:
a、將文件或文件夾封裝成對象,方便於對文件與文件夾的屬性信息進行操作。
b、File類的實例是不可變的;也就是說,一旦創建,File 對象表示的抽象路徑名將永不改變。
c、File對象可以作爲參數傳遞給流的構造函數。

2、File對象創建—— File 的構造方法

①File(String pathName)//根據指定路徑創建File對象。可以將已有的和未出現的文件或者文件夾封裝成對象。
      如: File f =new File("a.txt");。
②File(String pathName, String child)//根據指定的父路徑和子路徑(包括文件)創建文件對象。
      如: File f2=newFile("c:\\abc","b.txt")
③File(File parent, String child)//根據指定的File類型父路徑和子路徑創建文件對象,將文件目錄路徑封裝成對象降低了文件於父目錄的關聯性。
      如: File d=new File("c:\\abc");
            File f3=new File(d,"c.txt")
注意:File僅僅是一個路徑的表示,不代表具體的事物一定是存在的。

3、File類常用的成員方法

①創建功能

  • boolean createNewFile():在指定位置創建文件,如果該文件已經存在,則不創建,返回false。和輸出流不一樣,輸出流對象一建立創建文件。而且文件已經存在,會覆蓋。
  • boolean mkdir():創建文件夾,一次只能創建一個文件夾。
  • boolean mkdirs():創建多級文件夾。

②刪除功能

  • boolean delete():文件對象存在,返回true;不存在或者正在被執行,返回false
  • void deleteOnExit();在程序退出時刪除指定文件對象。

③判斷功能

  • boolean exists() :文件對象是否存在.
  • isFile():是否是文件
  • isDirectory();是否是文件夾
  • isHidden();是否是隱藏文件
  • isAbsolute();是否是絕對路徑
  • boolean renameTo(File file)://文件重命名
  •  boolean canExecute();//是否是可執行文件
記住:在判斷文件對象是否是文件或者目錄時,必須要判斷該文件對象封裝的內容是否存在。通過exists判斷。

④獲取信息功能

  • getName()://返回文件對象表示的文件或文件夾名稱
  • getParent()://返回File對象目錄的父目錄即不包含最後一級子目錄,如果是相對路徑且只有單極目錄則返回null
  • getPath()://獲取文件的相對路徑(即創建的對象傳入的參數是什麼就獲取到什麼)
  • getAbsolutePath()//獲取文件的絕對路徑 
  • long lastModified()//返回文件對象最後一次被修改的時間
  • long length() //返回文件長度,即文件大小

⑤列出文件及文件過濾功能

  • static File[] listRoots();//列出可用的文件系統根目錄,即系統盤符
  • String[] list();//列出當前目錄下所有文件的名稱,包括隱藏。該file對象必須是且該目錄還必須存在。
  • File[] listFiles();//獲取當前文件夾下的所有文件和文件夾
  • String[] list(FilenameFilter filter)//獲取目錄中滿足指定過濾器的文件,如:需要得到指定類型的文件。
  • FilenameFilter:文件名過濾器,是一個接口,其中包含一個方法accept(File dir,String name),返回的是boolean型,把不符合條件(即返回值爲false)的文件過濾
  • File[] ListFiles(FilenameFilter filter);//獲取目錄中滿足指定過濾器的文件或目錄,如果元素中還有子目錄,則需用到遞歸。
  • int compareTo(File pathName)//按字母順序比較兩個抽象路徑名
⑥重命名功能
  • publicbooleanrenameTo(Filedest) 重新命名文件
代碼演示:File類常用功能演示
package com.huang.io.file;

import java.io.File;
import java.io.IOException;

/*
 * File類常見方法演示
 */
public class FileDemo {

	public static void main(String[] args) throws IOException {
		method_5();
	}

	public static void method_5() {
		File f1 = new File("c:\\Test.java");
		File f2 = new File("d:\\hahah.java");

		sop("rename:" + f2.renameTo(f1));

	}

	public static void method_4() {
		File f = new File("file.txt");

		sop("path:" + f.getPath());
		sop("abspath:" + f.getAbsolutePath());
		sop("parent:" + f.getParent());// 該方法返回的是絕對路徑中的父目錄。如果獲取的是相對路徑,返回null。
										// 如果相對路徑中有上一層目錄那麼該目錄就是返回結果。

	}

	public static void method_3() throws IOException {
		File f = new File("d:\\java1223\\day20\\file2.txt");

		f.createNewFile();

		f.mkdir();

		// 記住在判斷文件對象是否是文件或者目的時,必須要先判斷該文件對象封裝的內容是否存在。
		// 通過exists判斷。
		sop("dir:" + f.isDirectory());
		sop("file:" + f.isFile());

		sop(f.isAbsolute());
	}

	public static void method_2() {
		File f = new File("file.txt");

		sop("exists:" + f.exists());

		sop("execute:" + f.canExecute());

		// 創建文件夾
		File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

		sop("mkdir:" + dir.mkdirs());
	}

	public static void method_1() throws IOException {
		File f = new File("file.txt");
		sop("create:" + f.createNewFile());
		sop("delete:" + f.delete());

	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}

二、遞歸

1、遞歸概述

遞歸就是方法定義中調用方法本身的現象。

2、遞歸注意事項

①要有出口,否則就是死遞歸。

②次數不能太多,否則會造成內存溢出。

③構造方法不能遞歸使用。

3、遞歸應用舉例(遞歸遍歷目錄)

package cn.itcast_03;

import java.io.File;

/*
 * 需求:把D:\java練習目錄下所有的java結尾的文件的絕對路徑給輸出在控制檯。
 * 
 * 分析:
 * 		A:封裝目錄
 * 		B:獲取該目錄下所有的文件或者文件夾的File數組
 * 		C:遍歷該File數組,得到每一個File對象
 * 		D:判斷該File對象是否是文件夾
 * 			是:回到B
 * 			否:繼續判斷是否以.java結尾
 * 				是:就輸出該文件的絕對路徑
 * 				否:不搭理它
 */
public class FilePathDemo {
	public static void main(String[] args) {
		// 封裝目錄
		File srcFolder = new File("D:\java練習");

		// 遞歸功能實現
		getAllJavaFilePaths(srcFolder);
	}

	private static void getAllJavaFilePaths(File srcFolder) {
		// 獲取該目錄下所有的文件或者文件夾的File數組
		File[] fileArray = srcFolder.listFiles();

		// 遍歷該File數組,得到每一個File對象
		for (File file : fileArray) {
			// 判斷該File對象是否是文件夾
			if (file.isDirectory()) {
				getAllJavaFilePaths(file);
			} else {
				// 繼續判斷是否以.java結尾
				if (file.getName().endsWith(".java")) {
					// 就輸出該文件的絕對路徑
					System.out.println(file.getAbsolutePath());
				}
			}
		}
	}
}

三、 Properties 類

1、概述

Properties 是 Hashtable 的子類,它具備Map集合的特點。而且它裏面還有存儲的鍵值對,都是字符串,無泛型定義。是集合中和IO技術想結合的集合容器。可用於鍵值對形式的配置文件

2、特有方法

①設置
    Object setProperty(String key,String value);//設置鍵和值,源碼是調用Hashtable的方法put(k,v)方法。
②獲取
    String getProperty(String key);//返回指定鍵所映射的值
    Set<String> stringPropertyName();//返回屬性列表的鍵集,存入Set集合

③加載流和存入流
a、將流中的數據加載進集合。
    void load(InputStream ism);//從輸入字節流中讀取屬性列表(鍵和元素對)
    void load(Reader reader);//從輸入字符流中讀取屬性列表(鍵和元素對)。又稱將流中的數據加載進集合。
b、將集合中數據加載進流
  • void store(OutputStreamout,String comments);//對應load(InputStream)將屬性列表(鍵值對)寫入輸出流。
  • void store(Writerwriter, String comments);//comments:屬性列表的描述即註釋。
④將屬性列表輸出到指定的輸出流。
  • void list(PrintStream out);
  • void list(PrintWriter out);
⑤練習:將文件中的鍵值對存儲到集合中
package com.huang.io.file;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
 *@author huangxiang
 *@date 創建時間:2015年5月26日上午1:53:29
 *@version 1.0
 */
/*
 * Properties練習
 * 將文件中的鍵值對存儲到集合中 。 
 * 思路: 1.創建讀取流對象並與文件關聯。
 *  	2.讀取一行數據,將該數據用“=”切割。
 * 		3.將等號左邊作爲建,右邊作爲值,存入集合中。
 */

public class PropertiesTest {
	public static void main(String[] args) throws IOException {
		method();
		// method_2();
	}

	// 方法一
	public static void method() {
		// 創建讀取流對象並與文件關聯。
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader("f:\\b.txt"));

			// 創建集合
			Properties pro = new Properties();

			String line = null;
			while ((line = br.readLine()) != null) {
				String[] str = line.split("=");
				pro.put(str[0], str[1]);

			}
			System.out.println(pro);
		} catch (Exception e) {
			throw new RuntimeException("文件讀取失敗");
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (Exception e) {
				throw new RuntimeException("流關閉失敗");
			}

		}

	}

	// 方法二
	public static void method_2() {
		// 創建讀取流對象,並和文件關聯。
		BufferedReader br = null;

		try {
			br = new BufferedReader(new FileReader("f:\\a.java"));
			// 創建集合
			Properties pro = new Properties();

			// 將流中數據加載進集合
			pro.load(br);

			System.out.println(pro);

		} catch (Exception e) {
			throw new RuntimeException("文件讀取失敗");
		}

		finally {
			try {
				if (br != null)
					br.close();
			} catch (Exception e) {
				throw new RuntimeException("流關閉失敗");
			}
		}

	}
}

四、打印流

1、字節打印流: PrintStream

構造函數可以接收的參數類型:
    1,file對象。 File
    2,字符串路徑。 String
    3,字節輸出流。 OutputStream

2、字符打印流: PrintWriter

構造函數可以接收的參數類型:
    1,file對象。File
    2,字符串路徑。String
    3,字節輸出流。OutputStream
    4,字符輸出流,Writer。

注意:當接收的參數是流時,其重載方法(out,boolean)可以創建帶自動刷新的打印流對象。
    如果 boolean 爲 true ,則 println、printf 或 format 方法將刷新輸出緩衝區
代碼演示如下:

package com.huang.io.file;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
/**
 *@author huangxiang
 *@date 創建時間:2015年5月27日上午2:06:30
 *@version 1.0
 */

/*
 * 打印流練習
 * 1.將鍵盤錄入的數據存入文本文件中。
 *  思路: 1.創建讀取流對象。
 *		 2.用寫入流創建文件 
 * 		 3.通過循環的讀寫將數據存入文件中。 
 *		 4.關閉資源。
 */

public class PrintTest {
	public static void main(String[] args) {
		BufferedReader br = null;
		PrintWriter pw = null;
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			pw = new PrintWriter(new FileWriter("src.txt"), true);

			String line = null;
			while ((line = br.readLine()) != null)// 一次讀取一行數據,判斷是否達到流末尾
			{
				if ("over".equals(line))
					break;
				pw.println(line);// 將數據寫入流中並刷新
			}

		} catch (Exception e) {
			System.out.println("文件寫入失敗");
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (Exception e) {
				System.out.println("讀取流關閉失敗");
			}
			try {
				if (pw != null)
					pw.close();
			} catch (Exception e) {
				System.out.println("寫入流關閉失敗");
			}
		}
	}
}


五、序列流

1、概述

①SequenceInputStream 對多個流進行合併。也被稱爲合併流。
②常用構造函數
    a、SequenceInputStream(InputStream s1, InputStream s2)//將兩個流合併
    b、SequenceInputStream(Enumeration<?extends FileInputStream> e)//將多個流合併
    方法1:創建Vector集合對象,將流添加進集合,在用elements()方法枚舉。
    方法2:創建ArrayList對象,將流加進集合,使用匿名內部類創建 Enumeration 子類對象並覆蓋其方法。
        這樣ArrayList中的流全部加進Enumeration中。

2、常見合併多個流文件步驟

    1、創建集合,並將流對象添加進集合
    2、創建Enumeration對象,將集合元素加入。
    3、創建SequenceInputStream對象,合併流對象
    4、創建寫入流對象,FileOutputStream關聯寫入文件
    5、利用SequenceInputStream對象和FileOutputStream對象對數據進行反覆讀寫操作。


練習一:將三個流合併爲一個

package com.huang.io.file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

/**
 * @author huangxiang
 * @date 創建時間:2015年5月26日上午1:59:27
 * @version 1.0
 */
// 四、序列流練習
/*
 * 1.將三個java文件合併到一個文本文件中。 
 * 思路: 1.創建Vector集合,將三個java文件字節流存入集合中。
 * 		2.創建Enumeration對象,將集合元素加入。 
 * 		3.創建SequenceInputStream對象,關聯Enumeration
 * 		4.創建輸出流關聯新文本文件。 5.循環讀寫數據。
 */

public class SequenceInputStreamTest {
	public static void main(String[] args) throws IOException {
		merge();

	}

	public static void merge() throws IOException {
		// 創建Vector集合合併流對象
		Vector<InputStream> v = new Vector<InputStream>();
		v.add(new FileInputStream("PrintTest.java"));
		v.add(new FileInputStream("FileTest.java"));
		v.add(new FileInputStream("Test.java"));

		// 創建Enumeration對象
		Enumeration<InputStream> en = v.elements();

		// 創建合併流對象,合併流
		SequenceInputStream sis = new SequenceInputStream(en);

		// 創建輸出流對象,寫入數據
		FileOutputStream fos = new FileOutputStream("merge.txt");

		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = sis.read(buf)) != -1) {
			fos.write(buf, 0, len);
		}
		// 關閉資源
		sis.close();
		fos.close();
	}
}


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