1. 程式人生 > 其它 >I/O流 基礎day-17

I/O流 基礎day-17

技術標籤:基礎java

1.I/O流
1.1 基本概念
I/O就是Input/Output的含義,也就是輸入/輸出的含義。
I/O流就是指像流水一樣不間斷地進行輸入輸出的過程。

1.2 基本分類
以讀寫資料的基本單位不同分為:位元組流 和 字元流。
其中位元組流主要指以位元組為單位進行讀寫的流,可以讀寫任意型別的檔案。
其中字元流主要指以字元(2個位元組)為單位進行讀寫的流,只能讀寫文字檔案。

以資料流動的方向不同分為:輸入流 和 輸出流(站在程式的角度)。
其中輸入流主要指從硬碟中的檔案讀取資料輸入到程式中。
其中輸出流主要指將程式中的資料輸出到檔案中,也就是寫檔案。

1.3 基本框架

位元組流的頂層父類:InputStream類 和 OutputStream類 - 抽象類
其中InputStream類的主要子類:
FileInputStream類、DataInputStream類、ObjectInputStream類。
其中OutputStream類的主要子類:
FileOutputStream類、DataOutputStream類、ObjectOutputStream類。

字元流的頂層父類:Reader類 和 Writer類 - 抽象類
其中Reader類的主要子類:
BufferedReader類、InputStreamReader類(轉換流)。
其中Writer類的主要子類:
BufferedWriter類、OutputStreamWriter類(轉換流)。

補充:
java.io.PrintStream類是OutputStream類的間接子類。
1.4 FileOutputStream類(重中之重)
(1)基本概念
java.io.FileOutputStream類主要用於將影象資料之類的原始位元組流寫入輸出流中。

(2)常用的方法
FileOutputStream(String name) - 根據引數指定的檔名來構造物件。
FileOutputStream(String name, boolean append) - 以追加的方式根據檔名來構造物件

void write(int b) - 用於將引數指定的單個位元組寫入輸出流中。
void write(byte[] b, int off, int len)
- 用於將陣列b中從下標off位置開始的len個位元組寫入輸出流中。
void write(byte[] b) - 用於將陣列b中的所有位元組寫入輸出流中。
void close() - 關閉輸出流並釋放有關的資源。

package cn.itxdl.day17;

import java.io.FileOutputStream;

public class TestFileOutputStream {

	public static void main(String[] args) {
		
		try{
			//1.構造FileOutputStream型別的物件與c:/a.txt檔案關聯
			//當檔案不存在時,該流會自動建立新的空檔案
			//當檔案存在時,該流會清空檔案中的原有內容
			FileOutputStream fos = new FileOutputStream("c:/a.txt");
			//以追加的方式關聯檔案,當檔案存在時不會清空檔案中的原有內容
			//FileOutputStream fos = new FileOutputStream("c:/a.txt", true);
			//2.通過輸出流向檔案中寫入資料  65 => A
			//byte b1 = 65;
			//System.out.println("b1 = " + b1); //b1 = 65
			//System.out.println("b1 = " + (char)b1); //A
			//實現向檔案中寫入單個位元組,會解析成對應的字元顯示
			//會將寫入的資料挨著存放到檔案中
			fos.write(65);  //'A'
			fos.write(66);  //'B'
			fos.write(67);  //'C'
			fos.write('6'); //'6'
			fos.write('5'); //'5'
			//實現向檔案中寫入字串"hello"
			fos.write("hello".getBytes());
			
			System.out.println("寫入資料成功!");
			//3.關閉流物件並釋放有關的資源
			fos.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}

1.5 FileInputStream類(重中之重)
(1)基本概念
java.io.FileInputStream類主要用於從輸入流中讀取影象資料之類的原始位元組流。

(2)常用的方法
FileInputStream(String name) - 根據引數指定的檔名來構造物件。
int read() - 用於從輸入流中讀取單個位元組。
- 成功返回實際讀取的資料內容,若返回-1則表示讀到檔案末尾。
int read(byte[] b, int off, int len)
- 用於從輸入流中讀取len個位元組放入陣列b中從off開始的位置。
- 成功返回實際讀取的資料大小,若返回-1則表示讀到檔案末尾。
int read(byte[] b)
- 用於從輸入流中讀取b.length個位元組的資料放入陣列b中。
int available() - 用於通過輸入流獲取檔案的大小。
void close() - 用於關閉流物件並釋放有關的資源。

package cn.itxdl.day17;

import java.io.FileInputStream;

public class TestFileInputStream {

	public static void main(String[] args) {
		
		try{
			//1.構造FileInputStream型別的物件與c:/a.txt檔案關聯
			FileInputStream fis = new FileInputStream("c:/a.txt");
			//2.從輸入流中讀取資料內容並打印出來
			/*
			int data = fis.read();
			System.out.println("讀取到的單個位元組是:" + (char)data); //65  A
			data = fis.read();
			System.out.println("讀取到的單個位元組是:" + (char)data); //66  B
			*/
			/*
			int data = 0;
			while((data = fis.read()) != -1){
				System.out.println("讀取到的單個位元組是:" + (char)data);
			}
			*/
			byte[] data = new byte[20];
			//期望從輸入流fis中一次性讀取20個位元組放入陣列data中
			//返回實際讀取到的資料大小
			//int res = fis.read(data);
			//期望從輸入流中讀取5個位元組放入陣列下標從2開始的位置  2 3 4 5 6
			int res = fis.read(data, 2, 5);
//			System.out.println("讀取到的資料內容是:" + new String(data) 
//					+ ",資料大小是:" + res);  //10
			System.out.println("讀取到的資料內容是:" + new String(data, 2, res) 
					+ ",資料大小是:" + res);  //10
			
			//3.關閉流物件並釋放有關的資源
			fis.close();
			//練習:實現c:/a.txt檔案到c:/b.txt檔案的拷貝。
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

練習檔案的拷貝:

package cn.itxdl.day17;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class TestFileCopy {

	public static void main(String[] args) {
		
		try{
			//1.構造FileInputStream型別的物件與c:/a.txt檔案關聯
			FileInputStream fis = new FileInputStream("D:/java22/day01/javaseday01-01-自我介紹和課程體系.wmv");
			//2.構造FileOutputStream型別的物件與c:/b.txt檔案關聯
			FileOutputStream fos = new FileOutputStream("c:/b.wmv");
			
			//3.不斷地從輸入流中讀取資料寫入到輸出流中
			System.out.println("正在玩命地拷貝...");
			//方式一:以位元組為單位進行資料的拷貝,當檔案稍大時則拷貝的效率極低
			/*
			int data = 0;
			while((data = fis.read()) != -1){
				fos.write(data);
			}
			*/
			//方式二:準備一個與檔案大小一樣的緩衝區,一次性將檔案的資料都讀取到緩衝區
			//       然後再一次性將整個緩衝區的所有資料寫入到目標檔案中
			//       當檔案非常大時,不可能做到申請一個與檔案大小一樣的陣列
			//       因為真實實體記憶體不足。
			/*
			int size = fis.available();
			System.out.println("檔案的大小是:" + size);
			byte[] bArr = new byte[size];
			//表示通過輸入流一次性讀滿整個陣列,也就是將檔案中的所有內容讀取出來
			int res = fis.read(bArr);
			System.out.println("實際讀取到的資料大小是:" + res); 
			//表示一次性將緩衝區中的所有內容寫入目標檔案中
			fos.write(bArr);
			*/
			//方式三:準備一個合理的緩衝區來讀取資料,然後再寫入資料
			//       無論檔案有多大,每次都只需要將緩衝區讀滿即可,可以讀很多次
			//       以後開發中推薦該方式
			byte[] bArr = new byte[1024*8];
			int res = 0;
			while((res = fis.read(bArr)) != -1){
				fos.write(bArr, 0, res);
			}
			
			System.out.println("拷貝檔案成功!");
			
			//4.關閉流物件並釋放有關的資源
			fos.close();
			fis.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

1.6 DataOutputStream類(查手冊會用即可)
(1)基本概念
java.io.DataOutputStream類主要用於將Java中基本資料型別的變數寫入輸出流。

(2)常用的方法
DataOutputStream(OutputStream out) - 根據引數指定的引用來構造物件。
- 其中OutputStream類是個抽象類,實參需要傳遞子類物件形成多型。
void writeInt(int v) - 用於將引數指定的整數按照四位元組方式寫入輸出流,先寫高位元組
- 如:127 => 0000 0000 0000 0000 0000 0000 0111 1111
高 => 低
void close()

package cn.itxdl.day17;

import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class TestDataOutputStream {

	public static void main(String[] args) {
		
		try{
			//1.構造DataOutputStream型別的物件與c:/a.txt檔案關聯
			DataOutputStream dos = new DataOutputStream(
					new FileOutputStream("c:/a.txt"));
			//2.準備一個int型別的變數並初始化,然後寫入輸出流中
			int num = 65;     //65: 0000 0000   0000 0000   0000 0000  0100 0001
			dos.writeInt(num); //寫入4個位元組  從高到低4個位元組全部寫入
			//dos.write(num);      //寫入1個位元組  只會將最低位的1個位元組寫入
			System.out.println("寫入整數資料成功!");
			//3.關閉流物件並釋放有關的資源
			dos.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

1.7 DataInputStream類(查手冊會用即可)
(1)基本概念
java.io.DataInputStream類主要用於從輸入流中讀取Java中基本資料型別的資料。

(2)常用的方法
DataInputStream(InputStream in) - 根據引數指定的引用來構造物件。
- 其中InputStream類是個抽象類,實參需要傳遞子類的物件形成多型。
int readInt() - 用於從輸入流中讀取一個整數並返回。
void close()

package cn.itxdl.day17;

import java.io.DataInputStream;
import java.io.FileInputStream;

public class TestDataInputStream {

	public static void main(String[] args) {
		
		try{
			//1.構造DataInputStream型別的物件與c:/a.txt檔案關聯
			DataInputStream dis = new DataInputStream(
					new FileInputStream("c:/a.txt"));
			//2.讀取檔案中的資料然後打印出來
			//int data = dis.readInt(); //一次性讀取4個位元組的資料然後合併為一個整數
			//System.out.println("讀取到的整數資料是:" + data); //65
			int data = dis.read();  //一次性讀取1個位元組
			System.out.println("data = " + data); //0
			data = dis.read();  //一次性讀取1個位元組
			System.out.println("data = " + data); //0
			data = dis.read();  //一次性讀取1個位元組
			System.out.println("data = " + data); //0
			data = dis.read();  //一次性讀取1個位元組
			System.out.println("data = " + data); //65
			
			//3.關閉流物件並釋放有關的資源
			dis.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

1.8 BufferedWriter類(重點)
(1)基本概念
java.io.BufferedWriter類用於寫入單個字元、字元陣列以及字串到輸出流中。

(2)常用的方法
BufferedWriter(Writer out) - 根據引數指定的引用來構造物件。
- 其中Writer類是個抽象類,實參需要傳遞子類物件形成多型。(轉換流的使用)
void write(int c) - 用於寫入單個字元。
void write(char[] cbuf, int off, int len)
- 用於將字元陣列cbuf中從下標off開始的len個字元寫入輸出流中。
void write(char[] cbuf) - 用於寫入整個字元陣列的內容。
void write(String str) - 用於寫入整個字串的內容。
void newLine() - 用於寫入一個行分隔符。
void close()

package cn.itxdl.day17;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class TestBufferedWriter {

	public static void main(String[] args) {
		
		try{
			//1.構造BufferedWriter型別的物件與c:/a.txt檔案關聯
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream("c:/a.txt")));
			//2.將資料內容寫入檔案中
			//表示寫入單個字元'1'
			bw.write('1');
			char[] cArr = {'h', 'e', 'l', 'l', 'o'};
			//表示寫入陣列cArr中從下標1開始的2個字元
			bw.write(cArr, 1, 2);
			//表示寫入陣列cArr中的所有內容
			bw.write(cArr);
			//表示寫入引數指定的整個字串
			bw.write("world");
			System.out.println("寫入資料成功!");
			//3.關閉流物件並釋放有關的資源
			bw.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

1.9 BufferedReader類(重點)
(1)基本概念
java.io.BufferedReader類用於從輸入流中讀取單個字元、字元陣列以及字串。

(2)常用的方法
BufferedReader(Reader in) - 根據引數指定的引用來構造物件。
- 其中Reader類是個抽象類,實參需要傳遞子類物件形成多型。(轉換流的使用)
int read() - 用於讀取單個字元。
int read(char[] cbuf, int off, int len)
- 用於讀取len個字元存放到陣列cbuf中下標從off開始的位置。
int read(char[] cbuf) - 用於讀滿整個字元陣列。
String readLine() - 用於讀取一行字串。
void close()

package cn.itxdl.day17;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class TestBufferedReader {

	public static void main(String[] args) {
		
		try{
			//1.構造BufferedReader型別的物件與c:/a.txt檔案關聯
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream("c:/a.txt")));
			//2.讀取檔案中的內容並打印出來
			//採用單個字元的方式讀取檔案中的所有內容
			/*
			 * int data = 0;
			while((data = br.read()) != -1){
				System.out.println("讀取到的單個字元是:" + (char)data);
			}
			*/
			/*
			 * char[] cArr = new char[1024];
			//表示從br中讀取10個字元存放到陣列cArr中下標從0開始的位置
			int res = br.read(cArr, 0, 10);
			System.out.println("讀取到的資料內容是:" + new String(cArr, 0, res));
			*/
			/*
			char[] cArr = new char[1024];
			int res = br.read(cArr);
			System.out.println("讀取到的資料內容是:" + new String(cArr, 0, res));
			*/
			String str = br.readLine();
			System.out.println("讀取到的資料內容是:" + str); //
			//3.關閉流物件並釋放有關的資源
			br.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}