1. 程式人生 > >Java之IO流 FileInputStream FileOputStream

Java之IO流 FileInputStream FileOputStream

位元組流(能夠處理任何型別的資料 因為計算機儲存都是以位元組為單位 byte 一個位元組八位) 總類為 位元組輸入流 InputStream 連線硬碟和記憶體之間的管道 讀取位元組 位元組輸出流 OutputStream 從記憶體輸出到硬碟中 下面講些常用的類

FileInputStream

注意在輸入的時候 方法中要丟擲 IOException 異常(因為可能讀入的過程中硬碟中可能沒有此檔案) 1.read() 方法 返回是個int值 其含義是檔案資料中的碼錶值 如a為97 b為98 。。 2.read(byte[ ])返回也是int值 其含義是讀入byte中的有效資料個數 3.read(byte[ ] ,int off ,int len)其中off表示起始偏移量 然後len表示 有效資料個數

一套典型的io流讀入程式碼

	FileInputStream fis = new FileInputStream("xxx.txt");	//建立流物件
		int b;
		while((b = fis.read()) != -1) {
			System.out.println(b);
		}
		
		fis.close();

下面說說 為什麼read 和 write 的返回值是int 而不是byte 按道理說檔案不都是以byte為基本單位儲存的嗎?幹嘛用int呢? 彆著急 在此之前你要明白 io流中有一個機制 那就是當檔案讀入完的時候 指標將會指向-1 來表示檔案讀入或輸出結束 假設 : 我用byte來作為返回值的話 讀入的過程中 可能會出現 11111111 這也是-1的補碼(計算機儲存的二進位制都是補碼格式 原碼取反加1) -1 的原碼 10000001 -1的反碼(第一位表示為符號位) 11111110 -1的補碼(反碼加1) 11111111 那麼就會出現自動返回的情況 導致檔案沒有完全讀入或輸出

那麼用int 的話 會預設給byte的數 自動新增 24個0 來消除這種情況 而結束的時候在用 int的-1來指向結束就好了 同時也不用擔心在java中輸出的時候前面的24個0會自動給刪掉 保證都是以原來的形式輸出

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

public class Demo1_FileInputStream {

	/**
	 * @param args
	 * @throws IOException  
	 * read()方法讀取的是一個位元組,為什麼返回是int,而不是byte
	 * 
	 * 00010100 00100100 01000001 11111111 0000000
	 * 
	 * 10000001    byte型別-1的原碼
	 * 11111110	   -1的反碼
	 * 11111111    -1的補碼
	 * 
	 * 00000000 00000000 00000000 11111111
	 */
public static void main(String[] args) throws IOException { //demo1(); FileInputStream fis = new FileInputStream("xxx.txt"); //建立流物件 int b; while((b = fis.read()) != -1) { System.out.println(b); } fis.close(); } public static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("xxx.txt"); //建立流物件 int x = fis.read(); //從硬碟上讀取一個位元組 System.out.println(x); int y = fis.read(); System.out.println(y); int z = fis.read(); System.out.println(z); int a = fis.read(); System.out.println(a); int b = fis.read(); System.out.println(b); fis.close(); //關流釋放資源 } }

FileOutputStream

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo2_FileOutputStream {

	/**
	 * @param args
	 * @throws IOException 
	 * FileOutputStream在建立物件的時候是如果沒有這個檔案會幫我創建出來
	 * 如果有這個檔案就會先將檔案清空
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		FileOutputStream fos = new FileOutputStream("yyy.txt",true);	//如果想續寫就在第二個引數傳true
		fos.write(97);
		fos.write(98);
		
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream("yyy.txt");		//建立位元組輸出流物件,如果沒有就自動建立一個
		//fos.write(97);				//雖然寫出的是一個int數,但是到檔案上的是一個位元組,會自動去除前三個8位
		//fos.write(98);
		//fos.write(99);
		fos.write(100);
		fos.close();
	}

}

實際操作中都是兩者結合一起使用 1.從demo1中可以看出來 輸入輸出的效率特別低 就好像我買100個雞蛋 我一次買一個回來 這麼一次次的來來回回 2.從demo3中可以看出來 使用大陣列的話 就好像我買100個雞蛋 我拿個容器(陣列)一次裝100個 拿回來就行 注意其中的 int len = fis.available(); 表示檔案的位元組個數 可是有個問題 那我位元組個數100萬呢? 我容器是不是得炸掉了?所以這種方法也不行

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

public class Demo3_Copy {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//demo2();
		//demo3();
	}

	public static void demo3() throws FileNotFoundException, IOException {
		//第二種拷貝,不推薦使用,因為有可能會導致記憶體溢位
		FileInputStream fis = new FileInputStream("致青春.mp3");		//建立輸入流物件,關聯致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//建立輸出流物件,關聯copy.mp3
		//int len = fis.available();
		//System.out.println(len);
		
		byte[] arr = new byte[fis.available()];						//建立與檔案一樣大小的位元組陣列
		fis.read(arr);												//將檔案上的位元組讀取到記憶體中
		fos.write(arr);												//將位元組陣列中的位元組資料寫到檔案上
		
		fis.close();
		fos.close();
	}

	public static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("致青春.mp3");		//建立輸入流物件,關聯致青春.mp3
		FileOutputStream fos = new FileOutputStream("copy.mp3");	//建立輸出流物件,關聯copy.mp3
		
		int b;
		while((b = fis.read()) != -1) {								//在不斷的讀取每一個位元組
			fos.write(b);											//將每一個位元組寫出
		}
		
		fis.close();												//關流釋放資源
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("雙元.jpg");		//建立輸入流物件,關聯雙元.jpg
		FileOutputStream fos = new FileOutputStream("copy.jpg");	//建立輸出流物件,關聯copy.jpg
		
		int b;
		while((b = fis.read()) != -1) {								//在不斷的讀取每一個位元組
			fos.write(b);											//將每一個位元組寫出
		}
		
		fis.close();												//關流釋放資源
		fos.close();
	}

}

這是最新的一種方法 小陣列的標準格式

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

public class Demo4_ArrayCopy {

	/**
	 * @param args
	 * 第三種拷貝
	 * 定義小陣列
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//demo2();
		FileInputStream fis = new FileInputStream("致青春.mp3");
		FileOutputStream fos = new FileOutputStream("copy.mp3");
		
		byte[] arr = new byte[1024 * 8];
		int len;
		while((len = fis.read(arr)) != -1) {				//如果忘記加arr,返回的就不是讀取的位元組個數,而是位元組的碼錶值
			fos.write(arr,0,len);
		}
		
		fis.close();
		fos.close();
	}

	public static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("xxx.txt");
		FileOutputStream fos = new FileOutputStream("yyy.txt");
		
		byte[] arr = new byte[2];
		int len;
		while((len = fis.read(arr)) != -1) {
			fos.write(arr,0,len);
		}
		
		fis.close();
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("xxx.txt");
		byte[] arr = new byte[2];
		int a = fis.read(arr);						//將檔案上的位元組讀取到位元組陣列中
		
		System.out.println(a);						//讀到的有效位元組個數
		for (byte b : arr) {						//第一次獲取到檔案上的a和b
			System.out.println(b);
		}
		System.out.println("-----------------------");
		int c = fis.read(arr);
		System.out.println(c);
		for (byte b : arr) {
			System.out.println(b);
		}
		fis.close();
	}

}