1. 程式人生 > >java中的io流之檔案操作

java中的io流之檔案操作

io流的檔案相關層次圖


File類

檔案是用來儲存資料的,目錄是管理檔案的特殊機制

在Java語言中,檔案和目錄的管理是由java.io.File類來實現的。File類也屬於java.io包,但它不是InputStream或者OutputStream的子類,因此不負責資料的輸入和輸出,而是專門管理磁碟的檔案和目錄。
每個File類的物件表示一個磁碟檔案或目錄,其物件屬性中包含了檔案或目錄的相關資訊,如名稱、長度、所含檔案個數等,呼叫它的方法則可以完成對檔案或目錄的常用管理操作,例如,建立、刪除等操作。

常用的File方法

判斷
		createNewFile()	        在指定位置建立一個空檔案,成功就返回true,如果已存在就不建立然後返回false
		mkdir()			在指定位置建立目錄,這隻會建立最後一級目錄,如果上級目錄不存在就拋異常。
		mkdirs()		在指定位置建立目錄,這會建立路徑中所有不存在的目錄。
		renameTo(File dest)	重新命名檔案或資料夾,也可以操作非空的資料夾,檔案不同時相當於檔案的剪下,剪下時候不能操作非空的資料夾。移動/重新命名成功則返回true,失敗則返回false。
		
刪除:
		delete()		刪除檔案或一個空資料夾,如果是資料夾且不為空,則不能刪除,成功返回true,失敗返回false。
		deleteOnExit()	在虛擬機器終止時,請求刪除此抽象路徑名錶示的檔案或目錄,保證程式異常時建立的臨時檔案也可以被刪除

判斷:
		exists()		檔案或資料夾是否存在。
		isFile()		是否是一個檔案,如果不存在,則始終為false。
		isDirectory()	是否是一個目錄,如果不存在,則始終為false。
		isHidden()		是否是一個隱藏的檔案或是否是隱藏的目錄。
		isAbsolute()	測試此抽象路徑名是否為絕對路徑名。

獲取:
		getName()		獲取檔案或資料夾的名稱,不包含上級路徑。
		getPath()       返回絕對路徑,可以是相對路徑,但是目錄要指定
		getAbsolutePath()	獲取檔案的絕對路徑,與檔案是否存在沒關係
		length()		獲取檔案的大小(位元組數),如果檔案不存在則返回0L,如果是資料夾也返回0L。
		getParent()		返回此抽象路徑名父目錄的路徑名字串;如果此路徑名沒有指定父目錄,則返回null。
		lastModified()	獲取最後一次被修改的時間。

資料夾相關:
		staic File[] listRoots()	列出所有的根目錄(Window中就是所有系統的碟符)
		list()				返回目錄下的檔案或者目錄名,包含隱藏檔案。對於檔案這樣操作會返回null。
		list(FilenameFilter filter)	返回指定當前目錄中符合過濾條件的子檔案或子目錄。對於檔案這樣操作會返回null。
		listFiles()			返回目錄下的檔案或者目錄物件(File類例項),包含隱藏檔案。對於檔案這樣操作會返回null。
		listFiles(FilenameFilter filter)返回指定當前目錄中符合過濾條件的子檔案或子目錄。對於檔案這樣操作會返回null。

流是指同一臺計算機或網路中不同計算機之間有序運動著的資料序列,Java把這些不同來源和目標的資料都統一抽象為資料流。流序列中的資料可以是沒有進行加工的原始資料(二進位制位元組資料),也可以是經過編碼的符合某種格式規定的資料,Java中提供了不同的流類對它們進行處理。

1.輸入流與輸出流

一個流,必有源端和目的端,它們可以是計算機記憶體的某些區域,也可以是磁碟檔案,甚至可以是Internet上的某個URL。流的方向是重要的,根據流的方向,流可分為兩類:輸入流和輸出流。使用者可以從輸入流中讀取資訊,但不能寫它。相反,對輸出流,只能往輸出流寫,而不能讀它。

1.1輸入流

在Java中,程式可以開啟一個輸入流,輸入流的資訊源可以位於檔案、記憶體或網路套接字(socket)等地方,資訊源的型別可以是包括物件、字元、影象、聲音在內的任何型別。一旦開啟輸入流後,程式就可從輸入流序列地讀資料。

1.2輸出流

類似地,程式也能通過開啟一個輸出流並按順序寫入資料來將資訊送至目的端。

2.位元組流與字元流

Java流包括位元組流和字元流,位元組流通過IO裝置以位元組資料的方式讀入,而字元流則通過位元組流讀入資料轉化成字元“流”的形式由使用者驅使。計算機並不區分二進位制檔案與文字檔案。所有的檔案都是以二進位制形式來儲存的,因此,從本質上說,所有的檔案都是二進位制檔案。所以字元流是建立在位元組流之上的,它能夠提供字元層次的編碼和解碼。例如,在寫入一個字元時,Java虛擬機器會將字元轉為檔案指定的編碼(預設是系統預設編碼),在讀取字元時,再將檔案指定的編碼轉化為字元。

位元組流示例(輸入輸出)

package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo04 {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub	
		writefile(new File("D:\\e.txt"));
		readfile(new File("D:\\e.txt"));
	}
	private static void readfile(File srcFile) throws IOException {
		// TODO Auto-generated method stub
		//建立從檔案到程式的流通道
		FileInputStream fileinputstream = new FileInputStream(srcFile);
		byte [] buf = new byte[1024];
		int len  = 0;
		//獲取檔案內容
		while((len = fileinputstream.read(buf))!= -1){
			System.out.println(new String(buf,0,len));
		}
	}
	private static void writefile(File destFile) throws IOException {
		// TODO Auto-generated method stub
		FileOutputStream fileoutstream = new FileOutputStream(destFile);
		String content  = "java io text";
		byte[] buf = content.getBytes();
		fileoutstream.write(buf);
		fileoutstream.close();
	}
	
}

字元流示例(輸入輸出)

package file;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
//字元流
public class Demo14 {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		writerToFile(new File("D:\\a.txt"));
		ReaderFromFile(new File("D:\\a.txt"));
	}
	private static void writerToFile(File path) throws IOException {
		// TODO Auto-generated method stub
		Writer fw = new FileWriter(path);
		char[] cbuf = "java io".toCharArray();
		fw.write(cbuf);
		fw.close();
	}
	private static void ReaderFromFile(File path) throws IOException {
		// TODO Auto-generated method stub
		Reader rd = new FileReader(path);
		char[] cbuf = new char[1024];
		int len = 0;
		while ((len = rd.read(cbuf))!= -1){
			System.out.println(cbuf);
		}
		rd.close();
	}
}

3.常用類應用示例

1. SequenceInputStream序列流,對多個流進行合併。

SequenceInputStream表示其他輸入流的邏輯串聯。它從輸入流的有序集合開始,並從第一個輸入流開始讀取,直到到達檔案末尾,接著從第二個輸入流讀取,依次類推,直到到達包含的最後一個輸入流的檔案末尾為止。

package file;
/*SequenceInputStream 表示其他輸入流的邏輯串聯。它從輸入流的有序集合開始,並從第一個輸入流開始讀取,直到到達檔案末尾,
接著從第二個輸入流讀取,依次類推,直到到達包含的最後一個輸入流的檔案末尾為止
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
public class Demo09 {
	public static void main(String[] args) throws IOException {
	
		String in1 = "D://a.txt";
		String in2 = "D://b.txt";
		String out = "D://k.txt";
		sis(in1,in2,out);
	}

	private static void sis(String in1, String in2, String out) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis1 = new FileInputStream(in1);
		FileInputStream fis2 = new FileInputStream(in2);
		FileOutputStream fos = new FileOutputStream(out);
		SequenceInputStream  s = new SequenceInputStream(fis1, fis2);
		int len = 0;
		byte[] buf = new byte[1024];
		while((len = s.read(buf))!= -1){
			fos.write(buf, 0, len);
		}
		s.close();
		fos.close();
	}
}

2.物件序列化 

ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時,可以為應用程式提供對物件圖形的持久儲存。ObjectInputStream 用於恢

復那些以前序列化的物件。其他用途包括使用套接字流在主機之間傳遞物件,或者用於編組和解組遠端通訊系統中的實參和形參。

物件的序列化:   將記憶體中的物件直接寫入到檔案裝置中

物件的反序列化: 將檔案裝置中持久化的資料轉換為記憶體物件

package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Demo12 {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub		
		person p1 = new person("Tom",22);	
		//序列化
		FileOutputStream fos = new FileOutputStream(new File("D:\\person\\a.txt"));	
		ObjectOutputStream oos = new ObjectOutputStream(fos);	
		oos.writeObject(p1);
		oos.close();
		fos.close();
		//反序列化
		FileInputStream fis = new FileInputStream(new File("D:\\person\\a.txt"));
		ObjectInputStream ois = new ObjectInputStream(fis);
		person p = (person)ois.readObject();
		System.out.println(p);		
	}
}
class person implements Serializable {
	/*類通過實現 java.io.Serializable 介面以啟用其序列化功能。
	未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子型別本身都是可序列化的。
	序列化介面沒有方法或欄位,僅用於標識可序列化的語義。
	如果物件沒有實現介面Serializable,在進行序列化時會丟擲:NotSerializableException 異常。*/
	private static final long serialVersionUID = 1L;
	/*serialVersionUID 用於給類指定一個UID。該UID是通過類中的可序列化成員的數字簽名運算出來的一個long型的值。
	只要是這些成員沒有變化,那麼該值每次運算都一樣。該值用於判斷被序列化的物件和類檔案是否相容。
	如果被序列化的物件需要被不同的類版本所相容。可以在類中自定義UID。定義方式:static final long serialVersionUID = 1L;*/
	public String name;
	public int age;
	public person(){
		
	}
	public person(String name , int age){
		this.name = name;
		this.age = age;
	}
	public String toString(){
		return "[姓名:"+name+",年齡:"+age+"]";
	}
}
3.Properties

可以和流相關聯的集合物件Properties.

Properties:該集合不需要泛型,因為該集合中的鍵值對都是String型別。

package file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

//Properties:該類是一個Map的子類,提供了可以快速操作配置檔案的方法
public class Demo15 {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		loadFile();
	}

	private static void loadFile() throws IOException {
		// TODO Auto-generated method stub
		//建立Properties物件
		Properties prop = new Properties();
		//建立流通道
		FileInputStream fis = new FileInputStream("D:\\ini.properties");
		//將配置檔案載入到Properties集合中
		prop.load(fis);
		// 通過鍵獲取指定的值
		Object object = prop.get("java");
		System.out.println(object);
		// 通過鍵修改值
		prop.setProperty("java", "77");
		// 將集合中的資料寫入到配置檔案中。
		FileOutputStream fos = new FileOutputStream("D:\\ini.properties");
		// 註釋:
		prop.store(fos, "text properties");	
		
		fis.close();
		fos.close();
	}
}
4.列印流
package file;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
public class Demo16 {
	public static void main(String[] args) throws IOException{
		
		/*PrintStream:是一個位元組列印流,System.out對應的型別就是PrintStream。*/
		PrintStream ps = System.out;
		ps.print("中國");
		ps.close();
		
		//輸出重定向
		PrintStream ps2 = new PrintStream(new File("D:\\log.txt"));
		System.setOut(ps2);
		ps2.print("內容輸出到指定的檔案log.txt中");
		
		//PrintWriter:是一個字元列印流
		PrintWriter pw = new PrintWriter("D:\\b.txt", "gbk");
		pw.append("中國");
		pw.close();	
	}
}
5.轉換流

InputStreamReader:位元組到字元的橋樑。

OutputStreamWriter:字元到位元組的橋樑。

package file;
//轉換流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Demo17 {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		File file = new File("D:\\a.txt");
		File fileGBK = new File("D:\\gbk.txt");
		File fileUTF = new File("D:\\utf.txt");
		// 寫入	
		testWriteFile(file);// 使用系統預設碼錶寫入
		testWriteFile(fileGBK, "gbk");// 使用gbk編碼向gbk檔案寫入資訊
		testWriteFile(fileUTF, "utf-8");// 使用utf-8向utf-8檔案中寫入資訊

		// 讀取		
		testReadFile(file);// 預設編碼
		testReadFile(fileGBK, "gbk");// 傳入gbk編碼檔案,使用gbk解碼	
		testReadFile(fileUTF, "utf-8");// 傳入utf-8檔案,使用utf-8解碼
	}
	private static void testReadFile(File file, String encod) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis,encod);
		int len = 0;
		char[] cbuf = new char[1024];
		while((len = isr.read(cbuf))!= -1){
			System.out.println(new String(cbuf,0,len));
		}
	}
	private static void testWriteFile(File file, String encod) throws IOException {
		// TODO Auto-generated method stub
		FileOutputStream fos = new FileOutputStream(file);
		OutputStreamWriter fosw = new OutputStreamWriter(fos,encod);
		fosw.write("指定格式編碼");
		fosw.close();
		fos.close();
	}
	private static void testReadFile(File file) throws IOException {
		// TODO Auto-generated method stub
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis);
		int len = 0;
		char[] cbuf = new char[1024];
		while((len = isr.read(cbuf))!= -1){
			System.out.println(new String(cbuf,0,len));
		}	
	}
	private static void testWriteFile(File file) throws IOException {
		// TODO Auto-generated method stub
		FileOutputStream fos = new FileOutputStream(file);
		OutputStreamWriter fosw = new OutputStreamWriter(fos);
		fosw.write("預設編碼");
		fosw.close();
		fos.close();	
	}
}