Java IO流知識彙總

java.io.File類的使用:java

File類用構造器建立其對象,此對象能夠對應文件,也能夠對應文件目錄。數組

File對象與平臺無關;File中的方法僅涉及到如何建立、刪除、重命名等操做,涉及到文件內容就要用到流了。app

經常使用方法:dom

File類的操做比較簡單,本身去看Api,renameTo():ide

file1.renameTo(file2):是將file1重命名爲file2,要求file1必須存在,file2必須不存在,纔可成功。(重命名原理是刪除了原來的文件從新建了一個文件)測試

File類的方法既能操做文件,又能操做目錄;this

建立刪除文件及目錄示例:編碼

public void createFile() throws IOException{
		File file1 = new File("D:\\io\\hello.txt");
		System.out.println(file1.delete());
		if(!file1.exists()){
			boolean b = file1.createNewFile();
			System.out.println(b);
		}
		
		File file2 = new File("D:\\io\\io2");
		System.out.println(file2.delete());
		if(!file2.exists()){
			boolean b = file2.mkdir();
			System.out.println(b);
		}
	}

mkdir和mkdirs區別在於:若是File路徑參數多級均不存在,就用mkdirs,能夠建立多個目錄,mkdir只能建立一個目錄,要求上級目錄存在的狀況下才返回true,mkdirs上級目錄不存在則一併建立。spa

list()方法返回的是字符串數組,至關於獲取相應目錄下的全部文件目錄,listFiles返回的是File數組,能夠對文件及目錄進行進一步操做。指針

Io原理經常使用流的分類:

原理

輸入:讀取外部數據(磁盤、光盤等存儲設備的數據)到程序(內存)中。

輸出:將程序(內存)數據輸出到磁盤、光盤等存儲設備中。

關係:(瞭解節點流和處理流的概念!如buffered*,節點流直接做用於文件)

文件流:FileInputStream/FileOutputStream/FileReader/FileWriter(從角色角度看是四個最基本的節點流;從處理單位不一樣的角度看前兩個是字節流,後兩個是字符流;從數據流向角度看一三是輸入流,二四是輸出流;每種流均可以拿到三個角度去看)

FileInputStream程序實例(具體注意見註釋)

public void testFileInputOutputStream(){
		//二、建立一個FileInputStream類的對象
		FileInputStream fis = null;
		try {
			//一、建立一個File類的對象
			File file = new File("hello.txt");
			fis = new FileInputStream(file);
			//三、調用FileInputStream類的方法,實現File文件的讀取。
		/*	int b;
			while((b = fis.read()) != -1){//這是一個字節一個字節的讀,效率低,開發時定義數據一次讀多個
				System.out.print((char)b);
			}*/
			byte[] b = new byte[5];//讀取到的數據要寫入的數組
			int len;//每次讀入到byte中的字節的長度
			while((len=fis.read(b)) != -1){
			/*	for(int i=0;i<len;i++){
					System.out.print((char)b[i]);
				}*/             //也能夠不用循環,改進以下「
				String str = new String(b, 0, len);//遍歷字符數組的時候考慮此構造方法,比循環效率高……
				System.out.print(str);
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
		//四、關閉輸入流
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

FileOutputStream程序實例(具體注意見註釋):

public void testFileOutputStream(){
		//一、建立一個File對象,代表要寫入的文件位置
		//輸出的物理文件能夠不存在,執行過程當中,不存在則自動建立,若存在會將原有的文件覆蓋
		File file = new File("hello2.txt");
		FileOutputStream fos = null;
		try {
			//二、建立一個FileOutputStream的對象,將File的對象作爲形參傳撿來
			fos = new FileOutputStream(file);
			//三、寫入操做
			fos.write(new String("I Love you!").getBytes());
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//四、關閉輸出流
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e .printStackTrace();
				}
			}
		}
	}

FileInputStream和FileOutputStream綜合程序實例(文件複製,複製任何格式的文件):

public void testFileInputOutputStream(){//使用字節流實現複製功能
		File file = new File("hello.txt");
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(file);
			fos = new FileOutputStream("aa.txt");
			byte[] b = new byte[5];
			int len;
			while((len=fis.read(b)) != -1){
				//String string = new String(b, 0, len);
				//fos.write(string.getBytes());
				fos.write(b, 0, len);;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

FileReader程序實例(具體注意見註釋):

public void testFileReader(){
		File file = new File("readerwriter.txt");
		FileReader reder = null;
		try {
			reder = new FileReader(file);
			char[] c = new char[24];
			int len;
			while((len = reder.read(c)) != -1){
				String string = new String(c, 0, len);
				System.out.print(string);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(reder != null){
				try {
					reder.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
		
	}

使用FileReader和FileWriter實現文本複製:(FileReader、FileWriter字符流只能操做文本文件,非文本文件(視頻、音頻、圖片)等其它格式的文件仍是要用字節流)

public void testFileReaderWriter(){//使用字符流實現複製功能
		FileReader fr = null;
		FileWriter fw = null;
		try {
			File file = new File("readerwriter.txt");
			fr = new FileReader(file);
			fw = new FileWriter("writer.txt");
			char[] c = new char[24];
			int len;
			while((len = fr.read(c)) != -1){
				fw.write(c, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fw != null){
				try {
					fw.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}finally{
					if(fr != null){
						try {
							fr.close();
						} catch (Exception e3) {
							e3.printStackTrace();
						}
					}
				}
			}
		}
	}

緩衝流:BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter處理流的一種,實際開發過程當中都用這四種,由於用這種處理流包裝字節流和字符流,效率大大增長,測試一個20kb的文件,用節點流使用17ms,使用buffered耗時4ms,而且文件越大優點越明顯,節點流的read方法是阻塞式的,bufferes是非阻塞式的使用bufferedoutputsteam和bufferedWriter最後要加上flush()方法,下面提供一個使用處理流的文件複製的方法,具體見註釋:

public void testBuffered() {//使用緩衝字節流實現文件複製的方法
		long start = System.currentTimeMillis();
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			//一、實現讀入、寫出的文件
			File file = new File("wife.jpg");
			File file1 = new File("shax.jpg");
			//二、想建立相應的節點流
			FileInputStream fis = new FileInputStream(file);
			FileOutputStream fos = new FileOutputStream(file1);
			//三、將建立的節點流的對象作爲形參傳遞給緩衝流的構造器中
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);
			//四、文件複製具體操做
			byte[] b = new byte[24];
			int len;
			while((len = bis.read(b)) != -1){
				bos.write(b, 0, len);
				bos.flush();//最後一次讀可能數組沒滿,把最後一點本身刷新進數組
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(bos != null){//使用緩衝流關流只須要關閉緩衝流,相關的字節流或字符流會自動關閉
				try {
					bos.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
			if(bis != null){
				try {
					bis.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
		long end = System.currentTimeMillis();
		System.err.println(end - start);
	}

緩衝字符流使用實例(在讀取和寫入字符的時候,除了支持讀寫字符,流還提供了讀寫一行字符串,readLine和write(String)具體見註釋):

public void testFileReaderWriter(){//使用字符流實現複製功能
		BufferedReader reader = null;
		BufferedWriter writer = null;
		try {
			File file = new File("readerwriter.txt");
			File file1 = new File("writer21.txt");
			FileReader fr = new FileReader(file);
			FileWriter fw = new FileWriter(file1);
			reader = new BufferedReader(fr);
			writer = new BufferedWriter(fw);
			String str;
			while((str = reader.readLine()) != null){
				writer.write(str);
				writer.newLine();//或是writer.write(str+"\n");由於程序讀取不會自動換行致使數據寫到一行
				writer.flush();
			}
			/*char[] c = new char[500];
			int len;
			while((len = reader.read(c)) != -1){
				writer.write(c, 0, len);
			}*///另外提供了讀取行
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(writer != null){
				try {
					writer.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}finally{
					if(reader != null){
						try {
							reader.close();
						} catch (Exception e3) {
							e3.printStackTrace();
						}
					}
				}
			}
		}
	}

轉換流:InputStreamReader/OutputStreamWriter(用於字節流和字符流之間的轉換,好比讀取文本文件使用字符流效率比較高,若是讀取到的是字節流,就能夠作轉換,使用頻率並非很高。解碼:字符數組->字符串;編碼:字符串->字符數組)

程序實例:

/**
如何實現字節流和字符流之間的轉換
	 * 轉換流:InputStreamReader  OutputStreamReader
	 * 解碼:字符數組->字符串
	 * 編碼:字符串->字符數組
	 */
	public void testSwitchStream(){
		//解碼
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			File file = new File("writer.txt");
			FileInputStream fis = new FileInputStream(file);
			InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
			br = new BufferedReader(isr);
			//編碼
			File file1 = new File("switch.txt");
			FileOutputStream fos = new FileOutputStream(file1);
			OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
			bw = new BufferedWriter(osw);
			String str;
			while((str = br.readLine()) != null){
				bw.write(str);
				bw.newLine();
				bw.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(bw != null){
				try {
					bw.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
			if(br != null){
				try {
					br.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
	}

標準輸入輸出流:(瞭解)

打印流:PrintStream/PrintWriter()

數據流:DataInputStream/DataOutputStream

數據流使用實例:

package com.review;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.junit.Test;

public class DataStream {

	@Test
	public void testDataOutputStream() {
		DataOutputStream dos = null;
		try {
			dos = new DataOutputStream(new FileOutputStream(new File("data.txt")));
			dos.writeUTF("你是否是傻,dhdh傻叉!");
			dos.writeBoolean(true);
			dos.writeLong(34567890);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (dos != null) {
				try {
					dos.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
	}
	
	@Test
	public void testInputStram(){
		DataInputStream dis = null;
		try {
			dis = new DataInputStream(new FileInputStream(new File("data.txt")));
			/*byte[] b = new byte[4];//這樣讀讀出來是亂碼,經過下面方式讀纔沒問題,至關於暗文
			int len;
			while((len=dis.read(b)) != -1){
				System.out.print(new String(b, 0, len));
			}*/
			System.out.println(dis.readUTF());
			System.out.println(dis.readBoolean());
			System.out.println(dis.readLong());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(dis != null){
				try {
					dis.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
		
	}
}

基本數據類型用數據流傳輸,引用數據類型就用對象流來進行傳輸:

對象流(涉及序列化、反序列化):ObjectInputStream/ObjectOutputStream:

    用於存儲和讀取對象的處理流,強大之處就是能夠把Java中的對象寫入到數據源中,也能夠把對象從數據源中還原回來。

序列化(Serialize):用ObjectOutputStream類將一個java對象寫入IO流中;

反序列化(Deserilize):用ObjectInputStream類從IO流中恢復該Java對象。

程序實例:

package com.qimeng;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.junit.Test;

public class TestObjectInputOutputStream {

	@Test
	//反序列化過程,將硬盤中的文件經過ObjectInputStream轉換位相應的對象
	public void testObjectInputStream(){
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream("person.txt"));
			Person p1 = (Person)ois.readObject();
			System.out.println(p1);
			Person p2 = (Person)ois.readObject();
			System.out.println(p2);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(ois != null){
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	@Test
	//對象的序列化過程,將內存中的對象經過ObjectOutputStream轉換爲二進制流,存在硬盤中
	public void testObjectOutputStream(){
		Person p1 = new Person("小米", 23);
		Person p2 = new Person("紅米", 21);
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
			oos.writeObject(p1);
			oos.flush();
			oos.writeObject(p2);
			oos.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(oos != null){
			try {
				oos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}
		}
	}
}
/**
 * 要實現序列化的類
 * 一、要求此類是可序列化的,因此必須實現Serializable或Extenalizable讓此類可序列化
 * 二、要求類的屬性一樣要實現Serializable接口。Serializable
 * 三、提供一個版本號
 * 四、這兩個對象流不能序列化static和transient修飾的成員變量
 */
class Person implements Serializable{
	private static final long serialVersionUID = 1807922889872508207L;//建議顯示標註
	String name;
	Integer age;
	public Person(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

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

serialVersionUID用來代表類的不一樣版本間的兼容性,若是類沒有顯示定義這個靜態變量,它的值是java運行時環境根據類的內部細節自動生成的,若類的源代碼作了修改,serialVersionUID可能發生改變,因此建議顯示聲明。

隨機存取文件流:RandomAccessFile類支持「隨機訪問」的方式,程序能夠直接跳到文件的任意地方來讀寫文件;也可向已存在的文件後追加內容;支持只訪問文件的部份內容。

具體詳細用法見程序實例:

package com.qimeng;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import org.junit.Test;
/**
 * RandomAccessFile:支持隨機訪問
 * 一、既能夠充當輸入流,也能夠充當輸出流
 * 二、支持從任意位置讀取、寫入(插入)
 */
public class TestRandomAccessFile {

	@Test
	//相較於test3,更通用
	public void test4(){
		RandomAccessFile raf = null;
		try {
			raf = new RandomAccessFile(new File("hello.txt"), "rw");
			raf.seek(4);//定位到d的指針
			byte[] b = new byte[10];
			int len;
			StringBuffer sb = new StringBuffer();
			while((len = raf.read(b)) != -1){
				sb.append(new String(b, 0, len));
			}
			raf.seek(4);
			raf.write("xy".getBytes());
			raf.write(sb.toString().getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(raf != null){
				try {
					raf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	@Test
	//實現插入的效果,向字符串abcdef123456的d後面插入「xy」
	public void test3(){
		RandomAccessFile raf = null;
		try {
			raf = new RandomAccessFile(new File("hello.txt"), "rw");
			raf.seek(4);//定位到d的指針
			String str = raf.readLine();//表示讀取了d後面的內容。此時指針在6後面,能夠用getFilePointer查看
			/*long f = raf.getFilePointer();
			System.out.println(f);*/
			raf.seek(4);//把指針調回去
			raf.write("xy".getBytes());
			raf.write(str.getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(raf != null){
				try {
					raf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@Test
	//向指定位置寫入,其實是覆蓋指定位置的字符
	public void test2(){
		RandomAccessFile raf = null;;
		try {
			raf = new RandomAccessFile(new File("hello.txt"), "rw");
			raf.seek(3);//從0開始,3表明從第四個字符後面開始寫
			raf.write("xy".getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(raf != null){
				try {
					raf.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
	}
	//進行文件的讀寫
	@Test
	public void test1(){
		RandomAccessFile raf1 = null;
		RandomAccessFile raf2 = null;
		try {
			raf1 = new RandomAccessFile(new File("hello.txt"), "r");
			raf2 = new RandomAccessFile(new File("hello1.txt"), "rw");
			byte[] b = new byte[5];
			int len;
			while((len = raf1.read(b)) != -1){
				raf2.write(b, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				raf2.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				raf1.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}
	
}

具體分類:

相關文章
相關標籤/搜索