Java:位元組流、字元流
1、IO概述- IO流概述及分類
1)、IO流:
I:Input(輸入):資料從外部流向程式中。(外部:檔案)
O:Ouput(輸出):資料從程式流向外部。
流:線性的,有方向的
2)、作用:
可以“讀”,“寫”檔案的內容,File類只能獲取檔案/目錄的一些屬性資訊,但不能讀寫檔案內容,只有IO流可以
3)、Java的IO流體系結構:
位元組流:按位元組讀寫檔案,可以操作任何型別檔案(純文字,二進位制…)
字元流:按字元讀寫檔案,僅可以讀寫純文字檔案
輸入流 | 輸出流 |
---|---|
位元組流 | 位元組輸入流InputStream |
字元流 | 字元輸入流Reader |
2、位元組流-一切皆位元組
1)、一切皆為位元組:任何檔案(純文字,二進位制…)最終在磁碟上儲存的都是“二進位制”,Java處理這些二進位制的最小單位就是“位元組(8位)”
2)、“位元組流”是Java中IO流中最基本的流,任何其他的流都是基於位元組流的
3、位元組流-位元組輸出流-父類OutputStream的輸出方式
1)、java.io.OutputStream
(抽象類):位元組輸出流的父類;
2)、定義輸出的方法:
public void close()
:關閉此輸出流並釋放與此流相關聯的任何系統資源。public void flush()
:重新整理此輸出流並強制任何緩衝的輸出位元組被寫出。public void write(byte[] b)
:輸出一個位元組陣列public void write(byte[] b, int off, int len)
:輸出位元組陣列的一部分(從索引為off處開始,往後len個數組元素)public abstract void write(int b)
:輸出一個位元組。
4、位元組流-位元組輸出流-子類FileOutputStream的輸出方法和追加寫入及換行
1)、java.io.FileOutputStream
(子類):是檔案輸出流,用於將資料寫出到檔案。
2)、構造方法:
public FileOutputStream(File file)
public FileOutputStream(String name)
: 使用指定檔名構造一個輸出流。覆蓋寫public FileOutputStream(File file, boolean append)
: 建立檔案輸出流以寫入由指定的 File物件表示的檔案。 追加寫public FileOutputStream(String name, boolean append)
: 建立檔案輸出流以指定的名稱寫入檔案。 追加寫注意:
1)、Java中任何輸出流,構造時檔案都可以不存在,會自動建立一個空的檔案。
2)、Java的IO流不要構造在一個存在的目錄上,會執行異常;如果是不存在的目錄,就會建立一個沒有後綴名的檔案
3)、操作同一個檔案時,FileOutputStream使用覆蓋寫的構造方法會把原檔案覆蓋
3)、輸出的方法:(沒有特殊方法,都是從父類繼承的)
write(byte[] b)
:輸出一個位元組陣列(write(“字串”.getBytes())),常用於輸出字串write(byte[] b, int off, int len)
:從指定的位元組陣列寫入 len位元組,從偏移量 off開始輸出到此輸出流。(從off開始,寫入往後len個位元組陣列元素)write(int b)
:輸出一個位元組。public static void main(String[] args) throws IOException { //1.FileOutputStream(String pathName) FileOutputStream out = new FileOutputStream("demo02.txt",true); //2.FileOutputStream(File file) // FileOutputStream out2 = new FileOutputStream(new File("demo02_2.txt")); //1.write(int b):輸出一個位元組 out.write(97); out.write(98); //2.write(byte[] byteArray):輸出多個位元組(一個byte[]陣列) String s = "你好"; out.write(s.getBytes()); out.write("\r\n".getBytes());//換行 out.write("97".getBytes()); out.write("\r\n".getBytes());//換行 //3.write(byte[] byteArray,int off,int len): byte[] byteArray = {97, 98, 99, 100, 101}; //只需要輸出:c,d,e out.write(byteArray,2,3); //關閉 out.close(); }
5、位元組流-位元組輸入流-父類InputStream的讀取方法
1)、java.io.InputStream
(抽象類):所有直接輸出流的父類;
2)、讀取的方法:
public void close()
:關閉此輸入流並釋放與此流相關聯的任何系統資源。public abstract int read()
:讀取一個位元組。public int read(byte[] b)
:讀取位元組陣列。(返回值是讀到的位元組陣列長度)
6、位元組流-位元組輸入流-子類FileInputStream的讀取方法
1)、java.io.FileInputStream
(子類)是檔案輸入流,從檔案中讀取位元組。
2)、構造方法:
FileInputStream(File file)
: 通過開啟與實際檔案的連線來建立一個 FileInputStream ,該檔案由檔案系統中的 File物件 file命名。FileInputStream(String name)
: 通過開啟與實際檔案的連線來建立一個 FileInputStream ,該檔案由檔案系統中的路徑名 name命名。注意:
1)、Java中所有的輸入流構造時,檔案必須存在,否則執行異常
2)、讀取的方法是從父類繼承的:
public int read()
:讀取一個位元組public int read(byte[] byteArray)
:讀取一個位元組陣列public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream("demo03.txt"); //1.讀取一個位元組 /* int b = 0; while((b = in.read()) != -1) { System.out.println("讀取的位元組:" + b); System.out.println("轉換為字元:" + (char) b); }*/ //2.讀取一個位元組陣列 byte[] byteArray = new byte[3]; int len = 0; while((len = in.read(byteArray)) != -1) { System.out.println("返回值:" + len); System.out.println("陣列內容:" + Arrays.toString(byteArray)); } in.close(); }
7、位元組流-位元組流練習-圖片複製
public static void main(String[] args) throws IOException {
//1.構造一個到原始檔的:輸入流
FileInputStream in = new FileInputStream("d:\\douyu.exe");
//2.構造一個到目標檔案的:輸出流
FileOutputStream out = new FileOutputStream("e:\\douyu_copy2.exe");//建立一個空檔案
//3.開始複製--慢
//1.一次讀、寫一個位元組
/*int b = 0;
while ((b = in.read()) != -1) {
out.write(b);
}
*/
//2.一次讀、寫多個位元組--快
byte[] byteArray = new byte[1024 * 8];
int len = 0;
while ((len = in.read(byteArray)) != -1) {
out.write(byteArray,0,len);
}
out.close();
in.close();
System.out.println("複製完畢!");
}
8、字元流-概述
1)、字元流:一次按一個字元讀取,每個國家的字元佔用的位元組數是不同的,(UTF-8,漢字佔用3個位元組)
2)、各個國家使用的編碼表不同,字元佔用的位元組數也就不同,如果都使用“位元組流”讀寫就會很不方便,所以Java提供了一種專門操作純文字檔案的字元流
9、字元流-字元輸出流-父類Writer的輸出方法
1)、java.io.Writer
(抽象類):所有字元輸出流的父類
2)、常用方法:
public abstract void close()
:關閉此輸出流並釋放與此流相關聯的任何系統資源。(自帶重新整理和關閉流)public abstract void flush()
:重新整理此輸出流並強制任何緩衝的輸出字元被寫出。public void write(int c)
:輸出一個字元public void write(char[] cbuf)
:輸出一個字元陣列public abstract void write(char[] b, int off, int len)
:輸出字元陣列的一部分public void write(String str)
:輸出一個字串
注意:在使用字元流輸出字元和字串後,字元流會建立一個快取區,必須對快取區進行重新整理(flush()或close()),才會寫入檔案中
10、字元流-字元輸出流-子類FileWriter類的使用
1)、java.io.FileWriter
(子類)
2)、構造方法:
FileWriter(File file)
: 建立一個新的 FileWriter,給定要讀取的File物件。FileWriter(String fileName)
: 建立一個新的 FileWriter,給定要讀取的檔案的名稱。FileWriter(String fileName,boolean append)
:構造一個FileWriter物件,給出一個帶布林值的檔名,表示是否附加寫入資料FileWriter(File file,boolean append)
: 建立一個新的 FileWriter,給定要讀取的File物件,布林值表示時候附加寫入資料public static void main(String[] args) throws IOException { FileWriter out = new FileWriter("demo06.txt");//覆蓋寫 // FileWriter out2 = new FileWriter("demo06.txt", true);//追加寫 //1.writer(int c): out.write('你'); out.write('a'); //2.write(char[] chArray) out.write("你好".toCharArray()); char[] chArray = {'a','b','你','好','啊','恩'}; out.write(chArray); //3.write(char[] chArray,int off,int len): //只輸出:好,啊,恩 out.write(chArray,3,3); //4.write(String s): out.write("呵呵"); out.write("\r\n"); //5.write(String s,int off,int len) String s = "我愛Java"; //要求輸出:s中的Java out.write(s,2,4); //out.flush();//重新整理快取區 out.close();//flush() + close()(建議) }
11、字元流-字元輸入流-父類Reader的讀取的方法
1)、java.io.Reader
(抽象類)
2)、常用方法:
public void close()
:關閉此流並釋放與此流相關聯的任何系統資源。public int read()
: 讀取一個字元,返回值:字元的編碼public int read(char[] cbuf)
:讀取一個字元陣列,返回值:字元數量
12、字元流-字元輸入流-子類-FileReader類的使用
1)、java.io.FileReader
(子類)
2)、構造方法:
FileReader(File file)
: 建立一個新的 FileReader ,給定要讀取的File物件。FileReader(String fileName)
: 建立一個新的 FileReader ,給定要讀取的檔案的名稱。public static void main(String[] args) throws IOException { File file = new File("demo07.txt"); if (!file.exists()) { file.createNewFile(); } FileReader in = new FileReader(file); //一次讀取一個字元 /*int c = 0; while ((c = in.read()) != -1) { System.out.println("讀取的字元:" + (char)c); }*/ //一次讀取一個字元陣列 char[] chArray = new char[2]; int len = 0; while ((len = in.read(chArray)) != -1) { System.out.println(chArray); } in.close(); }
13、IO異常處理-JDK7前的處理
public static void main(String[] args) {
FileReader in = null;
try {
in = new FileReader("demo07.txt");
//一次讀取一個字元陣列
char[] chArray = new char[2];
int len = 0;
while ((len = in.read(chArray)) != -1) {
System.out.println(chArray);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
14、IO異常處理-JDK7和JDK8的處理方式(開發常用)
public class Demo {
public static void main(String[] args) {
try (
//in物件不需要我們關閉,會自動關閉
FileReader in = new FileReader("demo07.txt");
) {
//一次讀取一個字元陣列
char[] chArray = new char[2];
int len = 0;
while ((len = in.read(chArray)) != -1) {
System.out.println(chArray);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
15、IO異常處理-JDK9改進的處理方式
public class Demo {
public static void main(String[] args) throws IOException {
//假設,這兩個物件不是我們建立的,從其它地方獲取的,但需要我們用完後關閉。
FileWriter out = new FileWriter("demo10.txt");
FileReader in = new FileReader("demo10_2.txt");
//寫在try(...)中的物件,在用完後會自動關閉。
try (in; out) {
char[] chArray = new char[1024];
int len = 0;
while ((len = in.read(chArray)) != -1) {
out.write(chArray, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
16、屬性集-Properties類概述
1)、java.util.Properties
(類):此類是一個Map集合
2)、此類中有倆個方法可以用於方便的讀、寫配置檔案;
3)、配置檔案:指軟體執行過程中記錄使用者的一些設定資訊的檔案,這種配置檔案在國際上有一個通用的格式:
名1 = 值;
名2 = 值;
這種格式與Map的鍵值對格式正好匹配,所以製作了一個Map集合,Properties方便讀取配置檔案
4)、Properties集合 –> 配置檔案;配置檔案 –>Properties集合
17、屬性集-Properties類與流相關的方法介紹
Properties集合 –> 配置檔案:store()方法
配置檔案 –>Properties集合:load()方法
public class Demo {
public static void main(String[] args) throws IOException {
// write();
read();
}
private static void read() throws IOException {
Properties pro = new Properties();
FileReader in = new FileReader("demo11.txt");
pro.load(in);//一次性將配置檔案中所有的鍵值對全部讀取到集合中
in.close();
/*Set<Object> keys = pro.keySet();
for (Object o : keys) {
System.out.println(o + " = " + pro.get(o));
}*/
Set<String> keys = pro.stringPropertyNames();
for (String k : keys) {
System.out.println(k + " = " + pro.getProperty(k));
}
}
private static void write() throws IOException {
Properties pro = new Properties();
pro.setProperty("金幣", "500000");//相當於:put(Object key,Object value)
pro.setProperty("鑽石", "200000");
pro.setProperty("疲勞", "120");
pro.setProperty("血量", "100");
//存到配置檔案
FileWriter out = new FileWriter("demo11.txt");
pro.store(out,"Hello");//將集合中所有的鍵值對一次性的寫入到檔案.
out.close();
}
}
複習
[ ] 能夠說出IO流的分類和功能
1)、位元組流:按位元組讀寫檔案,可以讀寫任何檔案
2)、字元流:按字元讀寫檔案,只能操作“純文字”檔案
[ ] 能夠使用位元組輸出流寫出資料到檔案
FileOutputStream out = new FileOutputStream("demo01.txt"); out.write(97); out.close();
[ ] 能夠使用位元組輸入流讀取資料到程式
FileInputStream in = new FileInputStream("demo01.txt"); byte[] bytes = new byte[1024]; int len = 0; while((len = in.read(bytes))!=-1){ String s = new String(bytes,0,len); System.out.println("讀取的內容:" + s); }
[ ] 能夠理解讀取資料read(byte[])方法的原理
[ ] 能夠使用位元組流完成檔案的複製
[ ] 能夠使用FileWirter寫資料到檔案
[ ] 能夠說出FileWriter中關閉和重新整理方法的區別
[ ] 能夠使用FileWriter寫資料的5個方法
[ ] 能夠使用FileWriter寫資料實現換行和追加寫
[ ] 能夠使用FileReader讀資料
[ ] 能夠使用FileReader讀資料一次一個字元陣列
[ ] 能夠使用Properties的load方法載入檔案中配置資訊