1. 程式人生 > 實用技巧 >第六章 檔案&IO流

第六章 檔案&IO流

6.1、File類

描述:該類是檔案和目錄路徑名的抽象表示

構造方法:

方法 描述
public File(String pathname) 通過將給定的路徑名字串轉換為抽象路徑名來建立新的File例項
public File(String parent, String child) 從父路徑名字串和子路徑名字串建立新的File例項
public File(File parent, String child) 從父抽象路徑名和子路徑名字串建立新的File例項

成員方法:

建立功能:

方法 描述
public boolean createNewFile() 當具有該名稱的檔案不存在時,建立一個由該抽象路徑名命名的新空檔案
public boolean mkdir() 建立由此抽象路徑名命名的單級目錄
public boolean mkdirs() 建立由此抽象路徑名命名的多級目錄

判斷功能:

方法 描述
public boolean isDirectory() 測試此抽象路徑名錶示的File是否為目錄
public boolean isFile() 測試此抽象路徑名錶示的File是否為檔案
public boolean exists() 測試此抽象路徑名錶示的File是否存在

獲取功能:

方法 描述
public String getAbsolutePath() 返回此抽象路徑名的絕對路徑名字串
public String getPath() 將此抽象路徑名轉換為路徑名字串
public String getName() 返回由此抽象路徑名錶示的檔案或目錄的名稱
public String[] list() 返回此抽象路徑名錶示的目錄中的檔案和目錄的名稱字串陣列
public File[] listFiles() 返回此抽象路徑名錶示的目錄中的檔案和目錄的File物件陣列

刪除功能:

方法 描述
public boolean delete() 刪除由此抽象路徑名錶示的檔案或目錄

6.2、IO流

概述:IO流就是用來處理裝置間資料傳輸問題的。常見的應用:檔案複製、檔案上傳、檔案下載、檔案的讀取、檔案的寫出等等

分類:

按照資料流向來分:
	輸入流:讀資料
	輸出流:寫資料
	
按照資料型別來分:
	位元組流
		位元組輸入流
		位元組輸出流
	字元流
		字元輸入流
		字元輸出流

注意:

  1. 如果操作的是純文字檔案,優先使用字元流
  2. 如果操作的是圖片、視訊、音訊、應用等二進位制檔案,優先使用位元組流
  3. 如果不確定檔案型別,優先使用位元組流,位元組流是萬能的流

6.2.1、位元組流

體系:

6.2.1.1、位元組流寫資料的三種方式

方法 描述
public void write(int b) 寫入一個位元組
public void write(byte[] b) 寫入一個位元組陣列
public void write(byte[] b, int off, int len) 寫入一個位元組陣列的一部分

6.2.1.2、位元組流讀資料的三種方式

方法 描述
public abstract int read() 讀入一個位元組
public int read(byte[] b) 讀入一個位元組陣列
public int read(byte[] b, int off, int len) 讀入一個位元組陣列的一部分

6.2.1.3、位元組流複製檔案的四種方式

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
	public static void main(String[] args) throws IOException {
		method1();
		method2();
		method3();
		method4();
	}

	// 基本位元組流一次讀寫一個位元組
	public static void method1() throws IOException {
		FileInputStream fis = new FileInputStream("sFolder\\demo.txt");
		FileOutputStream fos = new FileOutputStream("dFolder\\demo.txt");

		int by;
		while ((by = fis.read()) != -1) {
			fos.write(by);
		}

		fos.close();
		fis.close();
	}

	// 基本位元組流一次讀寫一個位元組陣列
	public static void method2() throws IOException {
		FileInputStream fis = new FileInputStream("sFolder\\demo.txt");
		FileOutputStream fos = new FileOutputStream("dFolder\\demo.txt");

		byte[] bys = new byte[1024];
		int len;
		while ((len = fis.read(bys)) != -1) {
			fos.write(bys, 0, len);
		}

		fos.close();
		fis.close();
	}

	// 位元組緩衝流一次讀寫一個位元組
	public static void method3() throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("sFolder\\demo.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("dFolder\\demo.txt"));

		int by;
		while ((by = bis.read()) != -1) {
			bos.write(by);
		}

		bos.close();
		bis.close();
	}

	// 位元組緩衝流一次讀寫一個位元組陣列
	public static void method4() throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("sFolder\\demo.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("dFolder\\demo.txt"));

		byte[] bys = new byte[1024];
		int len;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
		}

		bos.close();
		bis.close();
	}
}

6.2.2、字元流

體系:

6.2.2.1、字元流寫資料的五種方式

方法 描述
public void write(int c) 寫入一個字元
public void write(char[] cbuf) 寫入一個字元陣列
public void write(char[] cbuf, int off, int len) 寫入一個字元陣列的一部分
public void write(String str) 寫入一個字串
public void write(String str, int off, int len) 寫入一個字串的一部分

6.2.2.2、字元流讀資料的四種方式

方法 描述
public int read() 讀入一個字元
public int read(char[] cbuf) 讀入一個字元陣列
public int read(char[] cbuf, int offset, int length) 讀入一個字元陣列的一部分
public String readLine() 讀入一個字串

6.2.2.3、字元流複製文字的七種方式

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {
	public static void main(String[] args) throws IOException {
		method1();
		method2();
		method3();
		method4();
		method5();
		method6();
		method7();
	}

	// 基本字元流一次讀寫一個字元
	public static void method1() throws IOException {
		InputStreamReader isr = new InputStreamReader(new FileInputStream("sFolder\\demo.txt"));
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dFolder\\demo.txt"));

		int ch;
		while ((ch = isr.read()) != -1) {
			osw.write(ch);
		}

		osw.close();
		isr.close();
	}

	// 基本字元流一次讀寫一個字元陣列
	public static void method2() throws IOException {
		InputStreamReader isr = new InputStreamReader(new FileInputStream("sFolder\\demo.txt"));
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dFolder\\demo.txt"));

		char[] chs = new char[1024];
		int len;
		while ((len = isr.read(chs)) != -1) {
			osw.write(chs, 0, len);
		}

		osw.close();
		isr.close();
	}

	// 檔案字元流一次讀寫一個字元
	public static void method3() throws IOException {
		FileReader fr = new FileReader("sFolder\\demo.txt");
		FileWriter fw = new FileWriter("dFolder\\demo.txt");

		int ch;
		while ((ch = fr.read()) != -1) {
			fw.write(ch);
		}

		fw.close();
		fr.close();
	}

	// 檔案字元流一次讀寫一個字元陣列
	public static void method4() throws IOException {
		FileReader fr = new FileReader("sFolder\\demo.txt");
		FileWriter fw = new FileWriter("dFolder\\demo.txt");

		char[] chs = new char[1024];
		int len;
		while ((len = fr.read(chs)) != -1) {
			fw.write(chs, 0, len);
		}

		fw.close();
		fr.close();
	}

	// 字元緩衝流一次讀寫一個字元
	public static void method5() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("sFolder\\demo.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("dFolder\\demo.txt"));

		int ch;
		while ((ch = br.read()) != -1) {
			bw.write(ch);
		}

		bw.close();
		br.close();
	}

	// 字元緩衝流一次讀寫一個字元陣列
	public static void method6() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("sFolder\\demo.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("dFolder\\demo.txt"));

		char[] chs = new char[1024];
		int len;
		while ((len = br.read(chs)) != -1) {
			bw.write(chs, 0, len);
		}

		bw.close();
		br.close();
	}

	// 字元緩衝流特有功能複製文字檔案
	public static void method7() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("sFolder\\demo.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("dFolder\\demo.txt"));

		String line;
		while ((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
		}

		bw.close();
		br.close();
	}
}

6.3、資料夾複製

6.3.1、複製單級資料夾

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
	public static void main(String[] args) throws IOException {
		File srcFolder = new File("D:\\sFolder");
		File destFolder = new File("D:\\dFolder");
		copyFolder(srcFolder, destFolder);
	}

	/**
	 * 複製單級資料夾
	 * 
	 * @param srcFolder  原始檔夾
	 * @param destFolder 目的資料夾
	 * @throws IOException
	 */
	private static void copyFolder(File srcFolder, File destFolder) throws IOException {
		// 判斷路徑是否存在
		if (!destFolder.exists()) {
			destFolder.mkdirs();
		}
		// 獲取目的檔案列表
		File[] listFiles = srcFolder.listFiles();
		// 遍歷目的檔案列表
		for (File file : listFiles) {
			copyFile(file, new File(destFolder, file.getName()));
		}
	}

	/**
	 * 複製檔案
	 * 
	 * @param srcFile  原始檔
	 * @param destFile 目的檔案
	 * @throws IOException
	 */
	private static void copyFile(File srcFile, File destFile) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
		byte[] bys = new byte[1024];
		int len;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
		}
		bos.close();
		bis.close();
	}
}

6.3.2、複製多級資料夾

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
	public static void main(String[] args) throws IOException {
		File srcFolder = new File("D:\\sFolder");
		File destFolder = new File("D:\\dFolder");
		copyFolder(srcFolder, destFolder);
	}

	/**
	 * 複製多級資料夾
	 * 
	 * @param srcFolder  原始檔夾
	 * @param destFolder 目的資料夾
	 * @throws IOException
	 */
	private static void copyFolder(File srcFolder, File destFolder) throws IOException {
		// 判斷路徑是否存在
		if (!destFolder.exists()) {
			destFolder.mkdirs();
		}
		// 獲取目的檔案列表
		File[] listFiles = srcFolder.listFiles();
		// 遍歷目的檔案列表
		for (File file : listFiles) {
			if (file.isDirectory()) {
				copyFolder(file, new File(destFolder, file.getName()));
			} else {
				copyFile(file, new File(destFolder, file.getName()));
			}
		}
	}

	/**
	 * 複製檔案
	 * 
	 * @param srcFile  原始檔
	 * @param destFile 目的檔案
	 * @throws IOException
	 */
	private static void copyFile(File srcFile, File destFile) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
		byte[] bys = new byte[1024];
		int len;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
		}
		bos.close();
		bis.close();
	}
}

6.3.3、捕獲異常新特性

6.3.3.1、JDK7以前做法

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Main {
	public static void main(String[] args) {
		method();
	}

	private static void method() {
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("fr.txt");
			fw = new FileWriter("fw.txt");
			char[] chs = new char[1024];
			int len;
			while ((len = fr.read()) != -1) {
				fw.write(chs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

6.3.3.2、JDK7版本改進

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Main {
	public static void main(String[] args) {
		method();
	}

	private static void method() {
		try (FileReader fr = new FileReader("fr.txt"); 
			 FileWriter fw = new FileWriter("fw.txt");) {
			char[] chs = new char[1024];
			int len;
			while ((len = fr.read()) != -1) {
				fw.write(chs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

6.3.3.3、JDK9版本改進

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

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

	private static void method() throws IOException {
		FileReader fr = new FileReader("fr.txt");
		FileWriter fw = new FileWriter("fw.txt");
		try (fr; fw) {
			char[] chs = new char[1024];
			int len;
			while ((len = fr.read()) != -1) {
				fw.write(chs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

6.4、IO特殊流

6.4.1、標準輸入流

import java.io.IOException;
import java.io.InputStream;

public class Main {
	public static void main(String[] args) throws IOException {
		InputStream is = System.in;

		int by;
		while ((by = is.read()) != -1) {
			System.out.print((char) by);
		}

		is.close();
	}
}

6.4.2、標準輸出流

import java.io.IOException;
import java.io.PrintStream;

public class Main {
	public static void main(String[] args) throws IOException {
		PrintStream ps = System.out;

		ps.println("Hello,World");
		ps.write("Hello,World".getBytes());

		ps.close();
	}
}

6.4.3、位元組列印流

import java.io.IOException;
import java.io.PrintStream;

public class Main {
	public static void main(String[] args) throws IOException {
		PrintStream ps = new PrintStream("ps.txt");

		ps.println(97);
        ps.write(97);
		
		ps.close();
	}
}

6.4.4、字元列印流

import java.io.IOException;
import java.io.PrintWriter;

public class Main {
	public static void main(String[] args) throws IOException {
		PrintWriter pw = new PrintWriter("pw.txt");

		pw.println("hello");
		pw.write("Hello");

		pw.close();
	}
}

6.4.5、物件序列化流

注意:需要實現Serializable介面,同時需要給出serialVersionUID

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Student implements Serializable {
	private static final long serialVersionUID = 5923003911550370832L;
	private String name;
	private Integer age;

	public Student() {
		super();
	}

	public Student(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

public class Main {
	public static void main(String[] args) throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));

		Student s = new Student("曹晨磊", 30);
		oos.writeObject(s);

		oos.close();
	}
}

6.4.6、物件反序列化流

注意:成員變數加transient關鍵字修飾,該關鍵字標記的成員變數不參與序列化過程

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

class Student implements Serializable {
	private static final long serialVersionUID = 5923003911550370832L;
	private String name;
	private Integer age;

	public Student() {
		super();
	}

	public Student(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

public class Main {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));

		Object obj = ois.readObject();
		Student s = (Student) obj;
		System.out.println(s);

		ois.close();
	}
}

6.5、Properties集合

import java.util.Properties;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		Properties prop = new Properties();

		// 儲存元素
		prop.put("student1", "林青霞");
		prop.put("student2", "張曼玉");

		// 普通遍歷
		Set<Object> keySet = prop.keySet();
		for (Object key : keySet) {
			Object value = prop.get(key);
			System.out.println(key + "," + value);
		}

		// 特有方法
		prop.setProperty("student3", "趙雲");
		prop.setProperty("student4", "張飛");

		// 特有遍歷
		Set<String> names = prop.stringPropertyNames();
		for (String key : names) {
			String value = prop.getProperty(key);
			System.out.println(key + "," + value);
		}
	}
}
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class Main {
	public static void main(String[] args) throws IOException {
		// 把集合中的資料儲存到檔案
		myStore();
		// 把檔案中的資料載入到集合
		myLoad();
	}

	private static void myStore() throws IOException {
		Properties prop = new Properties();
		prop.setProperty("student1", "林青霞");
		prop.setProperty("student2", "張曼玉");
		FileWriter fw = new FileWriter("fw.txt");
		prop.store(fw, null);
		fw.close();
	}

	private static void myLoad() throws IOException {
		Properties prop = new Properties();
		FileReader fr = new FileReader("fw.txt");
		prop.load(fr);
		fr.close();
		System.out.println(prop);
	}
}