1. 程式人生 > >Java IO流基礎總結【一】

Java IO流基礎總結【一】

IO流

通過資料流、序列化和檔案系統提供系統輸入和輸出。流是一個很形象的概念,當程式需要讀取資料的時候,就會開啟一個通向資料來源的流,這個資料來源可以是檔案,記憶體,或是網路連線。類似的,當程式需要寫入資料的時候,就會開啟一個通向目的地的流。這時候你就可以想象資料好像在這其中“流”動一樣。就如水流、電流一樣,從一處通往另外一處。

java IO流體系

java.io.File:java程式中的此類的一個物件,就對應著硬碟中的一個檔案或網路中的一個資源。File既可以表示一個檔案,也可以表示一個目錄,File類的物件是與平臺無關的,File類針對的是檔案或者目錄,只能進行新建、刪除、重名令、上層目錄等這種面上的操作,真正設計到檔案內容的訪問讀取等,File是無能為力的,只能使用IO流下提供的相應的輸入輸出流來實現。

常把File類的物件作為形參傳遞給相應的輸入輸出流的構造器中。

IO流體系
分類位元組輸入流位元組輸出流字元輸入流字元輸出流
抽象基類InputStreamOutputStreamReaderWriter
訪問檔案FileInputStreamFileOutputStreamFileReaderFileWriter
訪問陣列ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
訪問管道PipedInputStreamPipedOutputStreamPipedReaderPipedWriter
訪問字串StringReaderStringWriter
緩衝流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
轉換流InputStreamReaderOutputStreamWriter
物件流ObjectInputStremObjectOutputStream
FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
列印流PrintStreamPrintWriter
推回輸入流PushbackInputStreamPushbackReader
特殊流DataInputStreamDataOutputStream

IO流的劃分

  • 按照流的流向不同(站在程式的角度來看):輸入流、輸出流
  • 按照流中資料單位的不同:位元組流、字元流(純文字檔案使用字元流,除此以外位元組流)
  • 按照流的角色不同:節點流、處理流(流直接作用在檔案上的是節點流,也叫檔案流(4個),除此以外都是處理流)


程式碼示例

java.io.File程式碼示例

package com.buerc.java.file;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.regex.Pattern;

import org.junit.Test;

public class FileTest {
	private static ArrayList<String> list=new ArrayList<>();
	@Test
	public void test(){
		listFileNames(File.separator+"home");
		System.out.println(list.size());
		for(String s:list){
			if(getFileNameWithRegex("(./*)+(conf.xml)$",s)){
				System.out.println(s);
			}
		}
		getFileNameWithFilter("(./*)+(.log)$",File.separator+"home");
	}
	//迭代獲取  如果是檔案直接add,如果是目錄,則迭代獲取
	public static void listFileNames(String fileName){
		File file=new File(fileName);
		if(file.exists()){
			if(!file.isDirectory()){
				list.add(file.getAbsolutePath());
			}else{
				File[] files=file.listFiles();
				for(File f:files){
					if(f.isDirectory()){
						listFileNames(f.getAbsolutePath());
					}else{
						list.add(f.getAbsolutePath());
					}
				}
			}
		}else{
			System.out.println(fileName+"檔案不存在");
		}
	}
	//過濾不符合條件的檔名
	public static boolean getFileNameWithRegex(String regex,String fileName){
		return Pattern.matches(regex, fileName);
	}
	//列出指定目錄下的合法檔案
	public static void getFileNameWithFilter(String filterStr,String filePath){
		File file=new File(filePath);
		String[] files=file.list(new FilenameFilter(){
			@Override
			public boolean accept(File dir, String name) {
				return Pattern.matches(filterStr, name);
			}
		});
		for(String s:files){
			System.out.println(s);
		}
	}
}

java.io體系下的其他的的操作高度相似,都是4個能夠直接訪問檔案的類new一個物件後進行read和write操作,再者就是像緩衝流這種類包裹之後進行處理加速檔案的讀取。

FileInputStream和FileOutputStream

package com.buerc.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

import org.junit.Test;

public class FileInputOutputStreamTest {
	@Test
	public void inputTest(){//這裡最好使用try catch而不是方法處直接丟擲異常,以防止後面的fis.close()執行不到,從而無法關閉io這種稀有資源
		File file=new File(File.separator+"home"+File.separator+"hechao"+File.separator+"hs_err_pid3304.log"); 
		FileInputStream fis=null;
		try {
			fis=new FileInputStream(file);
			byte[] b=new byte[1024];
			int len;
			try {
				while((len=fis.read(b))!=-1){
					System.out.println(new String(b,0,len));
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}finally{
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	@Test
	public void outputTest(){
		FileOutputStream fos=null;
		Scanner s=new Scanner(System.in);//鍵盤輸入
		try {
			fos=new FileOutputStream(File.separator+"home"+File.separator+"hechao"+File.separator+"test.txt");
			String str=s.nextLine();
			while(!("e".equalsIgnoreCase(str)||"exit".equalsIgnoreCase(str))){
				try {
					fos.write(str.getBytes());
					fos.write("\n".getBytes());
				} catch (IOException e) {
					e.printStackTrace();
				}
				str=s.nextLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}finally{
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			s.close();
		}
	}
	@Test//檔案複製
	public void inputOutputTest() {
		InputStream fis=null;
//		FileInputStream fis=null;
		FileOutputStream fos=null;
		try {
//			fis=new FileInputStream("hello.txt");//一定得存在不然拋FileNotFoundException,檔案存在於專案路徑下
			fis=this.getClass().getClassLoader().getResourceAsStream("hello.txt");
			fos=new FileOutputStream("hello_copy.txt");//可以不存在,存在就覆蓋,不存在就新建,檔案存在於src路徑下
			byte[] b=new byte[1024];
			int len;
			try {
				while((len=fis.read(b))!=-1) {
					fos.write(b, 0, len);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

FileReader和FileWriter

package com.buerc.file;

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

import org.junit.Test;

public class FileReaderWriterTest {
	@Test
	public void readerTest() {
		FileReader fr=null;
		try {
			fr=new FileReader("hello_copy.txt");
			char[] c=new char[1024];
			int len;
			try {
				while((len=fr.read(c))!=-1) {
					System.out.println(new String(c,0,len));
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	@Test
	public void writerTest() {
		FileWriter fw=null;
		try {
			fw=new FileWriter("test.txt");
			fw.write("javaIO基礎總結");
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	@Test
	public void readerWriterTest() {
		FileReader fr=null;
		FileWriter fw=null;
		try {
			fr=new FileReader("hello_copy.txt");
			fw=new FileWriter("test.txt");
			char[] c=new char[1024];
			int len;
			while((len=fr.read(c))!=-1) {
				fw.write(c, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

這4個類作為節點流直接作用在檔案上,兩兩一對,一對是位元組流一對是字元流,作為最基本的四個類。下篇總結作用在節點流上的處理流。