1. 程式人生 > >【基礎】-----IO流的理解

【基礎】-----IO流的理解

 1.檔案讀寫

       (1) java 檔案模型
             在硬碟上的檔案是byte byte byte儲存的,是資料的集合
     (2)開啟檔案
            有兩種模式“rw”讀寫  “r”只讀
            RandomAssessFile raf=new RandomAssessFile(file,"rw");
             檔案指標,開啟檔案時,指標在開頭  pointer=0
       (3)寫方法  


             raf.write('s')--->只寫一個位元組(後8位),同時指標移向下一個位置,準備再次寫入    
        (4)讀方法
              int b = raf.read()---->只讀一個位元組
     (5)檔案讀寫完成後一定要關閉

2.IO流

1.位元組流
 1)InputStream,OutPutStream
        InputStream抽象了應用程式讀取資料的方式
        OutputStream抽象了應用程式寫資料的方式

 2)EOF=End  讀到-1就是到了結尾
 3)輸入流的基本方法
      int b =in.read();讀取一個位元組無符號填充到int低八位
      in.read(byte[] buf)  讀取資料填充到位元組陣列
      in.read(byte[]buf,int start,int size)讀取資料到位元組陣列buf。從buf的start位置開始,存放size長度

   4)輸出流基本方法
       out.write(int b)    寫出一個byte到流,b的低八位
       out.write(byte[] buf)    將buf 位元組陣列都寫入到流
       out.write(byte[] buf,int start,int size)    位元組陣列buf從start位置開始寫size長度法的位元組到流

   5)FileInputStream---->具體實現了在檔案上讀取資料

package com.wisdomtraffic.common.MyTest;

import static org.junit.Assert.*;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.junit.Test;

public class IOUtil {
	/**
	 * 讀取指定檔案類容,按照16進位制輸出到控制檯
	 * 並每輸出10個byte換行
	 * @param FileName
	 * @throws Exception 
	 */
	private void printHex(String fileName) throws Exception {
		//把檔案作為位元組流進行讀操作
		FileInputStream in=new FileInputStream(fileName);
        int b;
        int i=1;
        while ((b=in.read())!=-1) {
//        	System.out.println(b);
			System.out.print(Integer.toHexString(b)+"  ");
			if (i++%10==0) {
				System.out.println();
			}
		}
	}
	/**
	 * 從in中批量讀取位元組,放入到buf這個位元組陣列中,
	 * 從第0個位置開始放,最多放buf.length個
	 * 返回的是讀到的位元組的個數。
	 * @param fileName
	 * @throws IOException
	 */
	private void printHexByByteArray(String fileName) throws IOException {
		FileInputStream in =new FileInputStream(fileName);
		byte[] bytes =new byte[1024*3];
		int b=0;
		while ((b=in.read(bytes, 0, bytes.length))!=-1) {
			for (int i = 0; i < b; i++) {    //b:讀到的有效位元組的個數
				System.out.println(Integer.toHexString(bytes[i]&0xff)+"   ");//int 32位,byte 8位,為避免資料轉換出問題,通過按位與將高24位清零
			}
		}
//		int 
	}
	
	@Test
	public void testName() throws Exception {
		printHexByByteArray("c:\\hyl\\hhh.txt");
	}
}

6)FileOutputStream--->實現了在檔案上寫出byte資料的方法

	//檔案copy
	private void copyFile(File srcFile,File dFile) throws Exception {
		if (!srcFile.exists()) {
			throw new IllegalArgumentException("檔案"+srcFile+"不存在");
		}
		FileInputStream in=new FileInputStream(srcFile);
		FileOutputStream out =new FileOutputStream(dFile);//若該檔案不存在則建立
		byte[] bytes=new byte[1024];
		int b;    //將位元組流讀到bytes陣列中
		while((b=in.read(bytes, 0, bytes.length))!=-1){
			out.write(bytes, 0, bytes.length);   //將位元組流從bytes資料組寫入新的檔案中
			out.flush();
		}
	}

 7)DateOutputStream/DateInputStream----->對“流”功能的擴充套件,可以更方便的讀取int,long,字元等型別的資料
      DateOutputStream    writeInt()/writeDouble()/writeUtf()......

8)BufferedInputStream&BufferedOutputStream   關閉流後要重新整理緩衝區  bos.flush();
   這兩個流類為IO提供了帶緩衝區的操作,一般開啟檔案進行寫入或讀取操作時,都會加上緩衝,這種流模式提高了IO的效能
   從應用程式中把資料放入檔案,相當於把一缸水倒入另一缸中
   FileOutputStream---->write()方法相當於把水一滴一滴的轉移
   DataUotputStream---->WriteXxx()方法更方便些,相當於一瓢一瓢轉移
   BufferedOutputStream---->write()相當於一瓢水先放入桶中,再從桶倒入另一缸中,效能提高了

2.字元流

1)編碼問題
2)認識文字和文字檔案
     java的文字(char)是16位無符號整數,是字元的unicode編碼(雙位元組編碼)
     文字是byte byte byte。。的資料數列
      文字檔案是文字(char)序列按照某種編碼方案utf-8,gbk等序列化為byte的儲存結果

3)字元流(Reader,Writer)
     字元的處理:一次處理一個字元,字元的底層仍然是基本的位元組序列
      InputStreamReader完成byte流解析為char流。按照編碼解析
      OutputStreamWriter提供char流到byte流,按照編碼處理

      如需要改變編碼,new InputStream(in,"utf-8")

 

FileWriter/FileReader

引數為TRUE 追加,不會刪除檔案中原有的內容

 

 

寫入檔案時不能換行,需要呼叫newLine()方法換行

物件的序列化與反序列化
1)序列化:將Object轉換成byte序列,反之叫物件的反序列化。
2)序列化流:(ObjectOutputStream)是過濾流---writeObject
      反序列化流:(ObjectInputStream)readObject
3)序列化介面(Serializable)
      物件必須實現序列化接口才能實現序列化,

transient關鍵字:該元素不會進行jvm預設的序列化,也可以自己進行這個元素的序列化