I/O流 基礎day-17
1.I/O流
1.1 基本概念
I/O就是Input/Output的含義,也就是輸入/輸出的含義。
I/O流就是指像流水一樣不間斷地進行輸入輸出的過程。
1.2 基本分類
以讀寫資料的基本單位不同分為:位元組流 和 字元流。
其中位元組流主要指以位元組為單位進行讀寫的流,可以讀寫任意型別的檔案。
其中字元流主要指以字元(2個位元組)為單位進行讀寫的流,只能讀寫文字檔案。
以資料流動的方向不同分為:輸入流 和 輸出流(站在程式的角度)。
其中輸入流主要指從硬碟中的檔案讀取資料輸入到程式中。
其中輸出流主要指將程式中的資料輸出到檔案中,也就是寫檔案。
1.3 基本框架
其中InputStream類的主要子類:
FileInputStream類、DataInputStream類、ObjectInputStream類。
其中OutputStream類的主要子類:
FileOutputStream類、DataOutputStream類、ObjectOutputStream類。
字元流的頂層父類:Reader類 和 Writer類 - 抽象類
其中Reader類的主要子類:
BufferedReader類、InputStreamReader類(轉換流)。
BufferedWriter類、OutputStreamWriter類(轉換流)。
補充:
java.io.PrintStream類是OutputStream類的間接子類。
1.4 FileOutputStream類(重中之重)
(1)基本概念
java.io.FileOutputStream類主要用於將影象資料之類的原始位元組流寫入輸出流中。
(2)常用的方法
FileOutputStream(String name) - 根據引數指定的檔名來構造物件。
FileOutputStream(String name, boolean append) - 以追加的方式根據檔名來構造物件
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();
}
}
}