今日内容介紹
1、位元組流
2、字元流
=======================第一節課開始=============================================
01輸入和輸出
* A:輸入和輸出
* a: 參照物
* 到底是輸入還是輸出,都是以Java程式為參照
* b: Output
* 把記憶體中的資料存儲到持久化裝置上這個動作稱為輸出(寫)Output操作
* 程式到檔案稱為輸出
* c: Input
* 把持久裝置上的資料讀取到記憶體中的這個動作稱為輸入(讀)Input操作
* 檔案到程式稱為輸入
* d: IO操作
* 把上面的這種輸入和輸出動作稱為IO操作
02位元組輸出流OutputStream
* A: 位元組輸出流OutputStream
* a.概念
* IO流用來處理裝置之間的資料傳輸
* Java對資料的操作是通過流的方式
* Java用于操作流的類都在IO包中
* 流按流向分為兩種:輸入流,輸出流。
* 流按操作類型分為兩種:
* 位元組流 : 位元組流可以操作任何資料,因為在計算機中任何資料都是以位元組的形式存儲的
* 字元流 : 字元流隻能操作純字元資料,比較友善。
* b.IO流常用父類
* 位元組流的抽象父類:
* InputStream
* OutputStream
* 字元流的抽象父類:
* Reader
* Writer
* c.IO程式書寫
* 使用前,導入IO包中的類
* 使用時,進行IO異常處理
* 使用後,釋放資源
* d: 方法介紹
* void close(): 關閉此輸出流并釋放與此流有關的所有系統資源。
* void write(byte[] b): 将 b.length 個位元組從指定的 byte 數組寫入此輸出流
* void write(byte[] b, int off, int len) :将指定 byte 數組中從偏移量 off 開始的 len 個位元組寫入此輸出流。
* abstract void write(int b) : 将指定的位元組寫入此輸出流。
03位元組輸出流FileOutputStream寫位元組
* A: 位元組輸出流FileOutputStream寫位元組
* a: FileOutputStream
* 寫入資料檔案,學習父類方法,使用子類對象
* b: FileOutputStream構造方法
* 作用:綁定輸出的輸出目的
* FileOutputStream(File file)
* 建立一個向指定 File 對象表示的檔案中寫入資料的檔案輸出流。
* FileOutputStream(File file, boolean append)
* 建立一個向指定 File 對象表示的檔案中寫入資料的檔案輸出流,以追加的方式寫入。
* FileOutputStream(String name)
* 建立一個向具有指定名稱的檔案中寫入資料的輸出檔案流。
* FileOutputStream(String name, boolean append)
* 建立一個向具有指定 name 的檔案中寫入資料的輸出檔案流,以追加的方式寫入。
* c: 流對象使用步驟
* 1. 建立流子類的對象,綁定資料目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
* d: 注意事項
* 流對象的構造方法,可以建立檔案,如果檔案存在,直接覆寫
* e: 案例代碼
/*
* FileOutputStream
* 寫入資料檔案,學習父類方法,使用子類對象
*
* 子類中的構造方法: 作用:綁定輸出的輸出目的
* 參數:
* File 封裝檔案
* String 字元串的檔案名
*
* 流對象使用步驟
* 1. 建立流子類的對象,綁定資料目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
*
* 流對象的構造方法,可以建立檔案,如果檔案存在,直接覆寫
*/
public class FileOutputStreamDemo {
public static void main(String[] args)throws IOException {
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流對象的方法write寫資料
//寫1個位元組
fos.write(97);
//關閉資源
fos.close();
}
}
04位元組輸出流FileOutputStream寫位元組數組
* A: 位元組輸出流FileOutputStream寫位元組數組
* a: 方法介紹
* void write(byte[] b): 将 b.length 個位元組從指定的 byte 數組寫入此輸出流
* void write(byte[] b, int off, int len) :将指定 byte 數組中從偏移量 off 開始的 len 個位元組寫入此輸出流。
* b: 案例代碼
/*
* FileOutputStream
* 寫入資料檔案,學習父類方法,使用子類對象
*
* 子類中的構造方法: 作用:綁定輸出的輸出目的
* 參數:
* File 封裝檔案
* String 字元串的檔案名
*
* 流對象使用步驟
* 1. 建立流子類的對象,綁定資料目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
*
* 流對象的構造方法,可以建立檔案,如果檔案存在,直接覆寫
*/
public class FileOutputStreamDemo {
public static void main(String[] args)throws IOException {
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流對象的方法write寫資料
//寫位元組數組
byte[] bytes = {65,66,67,68};
fos.write(bytes);
//寫位元組數組的一部分,開始索引,寫幾個
fos.write(bytes, 1, 2);
//寫入位元組數組的簡便方式
//寫字元串
fos.write("hello".getBytes());
//關閉資源
fos.close();
}
}
05檔案的續寫和換行符号
* A: 檔案的續寫和換行符号
* a: 檔案的續寫
* FileOutputStream構造方法, 的第二個參數中,加入true
* b: 換行符号
* 在檔案中,寫入換行,符号換行 \r\n
* \r\n 可以寫在上一行的末尾, 也可以寫在下一行的開頭
* c: 案例代碼
/*
* FileOutputStream 檔案的續寫和換行問題
* 續寫: FileOutputStream構造方法, 的第二個參數中,加入true
* 在檔案中,寫入換行,符号換行 \r\n
* \r\n 可以寫在上一行的末尾, 也可以寫在下一行的開頭
*/
public class FileOutputStreamDemo1 {
public static void main(String[] args)throws IOException {
File file = new File("c:\\b.txt");
FileOutputStream fos = new FileOutputStream(file,true);
fos.write("hello\r\n".getBytes());
fos.write("world".getBytes());
fos.close();
}
}
06IO中的異常處理
* A: IO中的異常處理
* a:IO流的異常處理
* try catch finally
* b: 細節
* 1. 保證流對象變量,作用域足夠
* 2. catch裡面,怎麼處理異常
* 輸出異常的資訊,目的看到哪裡出現了問題
* 停下程式,從新嘗試
* 3. 如果流對象建立失敗了,需要關閉資源嗎
* new 對象的時候,失敗了,沒有占用系統資源
* 釋放資源的時候,對流對象判斷null
* 變量不是null,對象建立成功,需要關閉資源
* c: 案例代碼
public class FileOutputStreamDemo3 {
public static void main(String[] args) {
//try 外面聲明變量,try 裡面建立對象
FileOutputStream fos = null;
try{
fos = new FileOutputStream("s:\\a.txt");
fos.write(100);
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("檔案寫入失敗,重試");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("關閉資源失敗");
}
}
}
}
07位元組輸入流InputStream
* A: 位元組輸入流InputStream
* a: 方法介紹
* abstract int read() :
* 從輸入流中讀取資料的下一個位元組。
* int read(byte[] b)
* 從輸入流中讀取一定數量的位元組,并将其存儲在緩沖區數組 b 中。
* int read(byte[] b, int off, int len)
* 将輸入流中最多 len 個資料位元組讀入 byte 數組。
* void close()
* 關閉此輸入流并釋放與該流關聯的所有系統資源。
* b: 案例代碼
/*
* 位元組輸入流
* java.io.InputStream 所有位元組輸入流的超類
* 作用: 讀取任意檔案,每次隻讀取1個位元組
* 讀取的方法 read
* int read() 讀取1個位元組
* int read(byte[] b) 讀取一定量的位元組,存儲到數組中
*/
public class InputStreamDemo {
}
08位元組輸入流FileInputStream讀取位元組
* A: 位元組輸入流FileInputStream讀取位元組
* a: 方法介紹
* abstract int read() :
* 從輸入流中讀取資料的下一個位元組,傳回-1表示檔案結束
* int read(byte[] b)
* 從輸入流中讀取一定數量的位元組,并将其存儲在緩沖區數組 b 中。
* 讀入緩沖區的位元組總數,如果因為已經到達檔案末尾而沒有更多的資料,則傳回 -1。
* int read(byte[] b, int off, int len)
* 将輸入流中最多 len 個資料位元組讀入 byte 數組。
* void close()
* 關閉此輸入流并釋放與該流關聯的所有系統資源。
* b: 案例代碼
/*
* FileInputStream讀取檔案
*
* 構造方法: 為這個流對象綁定資料源
*
* 參數:
* File 類型對象
* String 對象
* 輸入流讀取檔案的步驟
* 1. 建立位元組輸入流的子類對象
* 2. 調用讀取方法read讀取
* 3. 關閉資源
*
* read()方法,
* read()執行一次,就會自動讀取下一個位元組
* 傳回值,傳回的是讀取到的位元組, 讀取到結尾傳回-1
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException{
FileInputStream fis = new FileInputStream("c:\\a.txt");
//讀取一個位元組,調用方法read 傳回int
//使用循環方式,讀取檔案, 循環結束的條件 read()方法傳回-1
int len = 0;//接受read方法的傳回值
while( (len = fis.read()) != -1){
System.out.print((char)len);
}
//關閉資源
fis.close();
}
}
/*
* int i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
*/
09位元組輸入流FileInputStream讀取位元組數組
* A: 位元組輸入流FileInputStream讀取位元組數組
* a: 方法介紹
* int read(byte[] b)
* 從輸入流中讀取一定數量的位元組,并将其存儲在緩沖區數組 b 中。
* 讀入緩沖區的位元組總數,如果因為已經到達檔案末尾而沒有更多的資料,則傳回 -1。
* int read(byte[] b, int off, int len)
* 将輸入流中最多 len 個資料位元組讀入 byte 數組。
* b: 案例代碼
/*
* FileInputStream讀取檔案
* 讀取方法 int read(byte[] b) 讀取位元組數組
* 數組作用: 緩沖的作用, 提高效率
* read傳回的int,表示什麼含義 讀取到多少個有效的位元組數
*/
public class FileInputStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("c:\\a.txt");
// 建立位元組數組
byte[] b = new byte[2];
int len = fis.read(b);
System.out.println(new String(b));// ab
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// cd
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// 1
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// -1
fis.close();
}
}
10位元組輸入流FileInputStream讀取位元組數組的實作原理
* A:位元組輸入流FileInputStream讀取位元組數組的實作原理
* a: 原理
* 參見day23_source檔案夾中的"讀取數組的原理.jpg"
* b: 案例代碼
public class FileInputStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("c:\\a.txt");
//建立位元組數組
byte[] b = new byte[1024];
int len = 0 ;
while( (len = fis.read(b)) !=-1){
System.out.print(new String(b,0,len));
}
fis.close();
}
}
11檔案複制原理
* A: 檔案複制原理
* a: 見day23_source/檔案複制原理.jpg
12位元組流複制檔案讀取單個位元組
* A: 位元組流複制檔案讀取單個位元組
* a: 案例代碼
/*
* 将資料源 c:\\a.txt
* 複制到 d:\\a.txt 資料目的
* 位元組輸入流,綁定資料源
* 位元組輸出流,綁定資料目的
*
* 輸入,讀取1個位元組
* 輸出,寫1個位元組
*/
public class Copy {
public static void main(String[] args) {
//定義兩個流的對象變量
FileInputStream fis = null;
FileOutputStream fos = null;
try{
//建立兩個流的對象,綁定資料源和資料目的
fis = new FileInputStream("c:\\t.zip");
fos = new FileOutputStream("d:\\t.zip");
//位元組輸入流,讀取1個位元組,輸出流寫1個位元組
int len = 0 ;
while((len = fis.read())!=-1){
fos.write(len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("檔案複制失敗");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
}
}
13位元組流複制檔案讀取位元組數組
* A: 位元組流複制檔案讀取位元組數組
* a: 案例代碼
/*
* 位元組流複制檔案
* 采用數組緩沖提高效率
* 位元組數組
* FileInputStream 讀取位元組數組
* FileOutputStream 寫位元組數組
*/
public class Copy_1 {
public static void main(String[] args) {
long s = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream("c:\\t.zip");
fos = new FileOutputStream("d:\\t.zip");
//定義位元組數組,緩沖
byte[] bytes = new byte[1024*10];
//讀取數組,寫入數組
int len = 0 ;
while((len = fis.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("檔案複制失敗");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
long e = System.currentTimeMillis();
System.out.println(e-s);
}
}
14編碼表
* A: 編碼表
* a: 定義:
* 生活中字元和計算機二進制的對應關系表,就是編碼表
* b: 分類
* 1、ascii: 一個位元組中的7位就可以表示。對應的位元組都是正數。0-xxxxxxx
* 2、iso-8859-1:拉丁碼表 latin,用了一個位元組用的8位。1-xxxxxxx 負數。
* 3、GB2312:簡體中文碼表。包含6000-7000中文和符号。用兩個位元組表示。兩個位元組第一個位元組是負數,第二個位元組可能是正數
* GBK:目前最常用的中文碼表,2萬的中文和符号。用兩個位元組表示,其中的一部分文字,第一個位元組開頭是1,第二位元組開頭是0
* GB18030:最新的中文碼表,目前還沒有正式使用。
* 4、unicode:國際标準碼表:無論是什麼文字,都用兩個位元組存儲。
* Java中的char類型用的就是這個碼表。char c = 'a';占兩個位元組。
* Java中的字元串是按照系統預設碼表來解析的。簡體中文版 字元串預設的碼表是GBK。
* 5、UTF-8:基于unicode,一個位元組就可以存儲資料,不要用兩個位元組存儲,而且這個碼表更加的标準化,在每一個位元組頭加入了編碼資訊(後期到api中查找)。
* 6、能識别中文的碼表:GBK、UTF-8;正因為識别中文碼表不唯一,涉及到了編碼解碼問題。
* 對于我們開發而言;常見的編碼 GBK UTF-8 ISO-8859-1
* 文字--->(數字) :編碼。 “abc”.getBytes() byte[]
* (數字)--->文字 : 解碼。 byte[] b={97,98,99} new String(b)
15字元輸出流寫文本FileWriter類
* A: 字元輸出流寫文本FileWriter類
* a: 方法介紹
* void write(int c)
* 寫入單個字元
* void write(String str)
* 寫入字元串
* void write(String str, int off, int len)
* 寫入字元串的某一部分
* void write(char[] cbuf)
* 寫入字元數組
* abstract void write(char[] cbuf, int off, int len)
* 寫入字元數組的某一部分
* b: 案例代碼
/*
* 字元輸出流
* java.io.Writer 所有字元輸出流的超類
* 寫檔案,寫文本檔案
*
* 寫的方法 write
* write(int c) 寫1個字元
* write(char[] c)寫字元數組
* write(char[] c,int,int)字元數組一部分,開始索引,寫幾個
* write(String s) 寫入字元串
*
* Writer類的子類對象 FileWriter
*
* 構造方法: 寫入的資料目的
* File 類型對象
* String 檔案名
*
* 字元輸出流寫資料的時候,必須要運作一個功能,重新整理功能
* flush()
*/
public class WriterDemo {
public static void main(String[] args) throws IOException{
FileWriter fw = new FileWriter("c:\\1.txt");
//寫1個字元
fw.write(100);
fw.flush();
//寫1個字元數組
char[] c = {'a','b','c','d','e'};
fw.write(c);
fw.flush();
//寫字元數組一部分
fw.write(c, 2, 2);
fw.flush();
//寫如字元串
fw.write("hello");
fw.flush();
fw.close();
}
}
16字元輸入流讀取文本FileReader類
* A: 字元輸入流讀取文本FileReader類
* a: 方法介紹
* int read()
* 讀取單個字元
* int read(char[] cbuf)
* 将字元讀入數組
* abstract int read(char[] cbuf, int off, int len)
* 将字元讀入數組的某一部分。
* b: 案例代碼
/*
* 字元輸入流讀取文本檔案,所有字元輸入流的超類
* java.io.Reader
* 專門讀取文本檔案
*
* 讀取的方法 : read()
* int read() 讀取1個字元
* int read(char[] c) 讀取字元數組
*
* Reader類是抽象類,找到子類對象 FileReader
*
* 構造方法: 綁定資料源
* 參數:
* File 類型對象
* String檔案名
*/
public class ReaderDemo {
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("c:\\1.txt");
/*int len = 0 ;
while((len = fr.read())!=-1){
System.out.print((char)len);
}*/
char[] ch = new char[1024];
int len = 0 ;
while((len = fr.read(ch))!=-1){
System.out.print(new String(ch,0,len));
}
fr.close();
}
}
17flush方法和close方法差別
* A: flush方法和close方法差別
*a: flush()方法
* 用來重新整理緩沖區的,重新整理後可以再次寫出,隻有字元流才需要重新整理
*b: close()方法
* 用來關閉流釋放資源的的,如果是帶緩沖區的流對象的close()方法,不但會關閉流,還會再關閉流之前重新整理緩沖區,關閉後不能再寫出
18字元流複制文本檔案
* A: 字元流複制文本檔案
* a: 案例代碼
/*
* 字元流複制文本檔案,必須文本檔案
* 字元流查詢本機預設的編碼表,簡體中文GBK
* FileReader讀取資料源
* FileWriter寫入到資料目的
*/
public class Copy_2 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("c:\\1.txt");
fw = new FileWriter("d:\\1.txt");
char[] cbuf = new char[1024];
int len = 0 ;
while(( len = fr.read(cbuf))!=-1){
fw.write(cbuf, 0, len);
fw.flush();
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("複制失敗");
}finally{
try{
if(fw!=null)
fw.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fr!=null)
fr.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
}
}
19總結
* 把今天的知識點總結一遍。