java入門(字元流、位元組流)

Li_CSDN_Li發表於2020-10-24

字元流、位元組流

位元組流(輸出流)

1.IO概述

I:Input 輸入

O:output 輸出
在這裡插入圖片描述

頂層父類:
在這裡插入圖片描述

2.位元組輸出流基本使用
  • OutputStream抽象類是表示位元組輸出流的所有類的超類,因為這個父類是一個抽象類,不能直接建立物件,如果要使用需要藉助其子類FileOutputStream

  • 如何使用位元組輸出流?
    1)創:建立輸出流物件
    2)寫:藉助流物件呼叫write方法寫出資料
    3)關:關閉流資源 close

  • 構造方法

    public FileOutputStream(File file)
    public FileOutputStream(String file)
    
    public FileOutputStream(File file,boolean append)
    public FileOutputStream(String file,boolean append)
    構造方法中都要關聯一個檔案【不管是檔案物件,或者一個字串檔案路徑】
    
  • 常用的方法

    - public void close() :關閉此輸出流並釋放與此流相關聯的任何系統資源。
    - public void flush() :重新整理此輸出流並強制任何緩衝的輸出位元組被寫出。
    - public void write(byte[] b):將 b.length位元組從指定的位元組陣列寫入此輸出流。
    - public void write(byte[] b, int off, int len) :從指定的位元組陣列寫入 len位元組,從偏移量 off開始輸出到此輸出流。
    - public abstract void write(int b) :將指定的位元組輸出流。
    

【程式碼實踐】

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1)創:建立輸出流物件
        //關聯檔案,用來儲存輸出的資料
        //public FileOutputStream(File file)
        //FileOutputStream fos = new FileOutputStream(new File("file10.txt"));
        //public FileOutputStream(String file)
        FileOutputStream fos = new FileOutputStream("file10.txt");

        //2)寫:藉助流物件呼叫write方法寫出資料
        byte[] bytes = "Hello".getBytes();
        fos.write(bytes);

        //3)關:關閉流資源 close
        fos.close();

    }
}
3.位元組輸出流構造方法

FileOutputStream構造方法:
沒有拼接功能:
每次關聯檔案時:如果檔案不存在,會直接建立,如果存在會把內容清空

public FileOutputStream(File file)
public FileOutputStream(String file)

內部原理,就是呼叫了含有append的構造方法,把append預設為false

有拼接功能:

public FileOutputStream(File file,boolean append): 當第二個引數append為true時,具有拼接功能
public FileOutputStream(String file,boolean append): 當第二個引數append為true時,具有拼接功能

構造方法中都要關聯一個檔案【不管是檔案物件,或者一個字串檔案路徑】

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1.創
        //沒有拼接功能
        // FileOutputStream fos = new FileOutputStream("file11.txt");
        //有拼接功能
        FileOutputStream fos = new FileOutputStream("file11.txt", true);
         
        //2.寫
        fos.write("CCCCC".getBytes());
        //3.關

        fos.close();

    }
}

4.位元組輸出流的寫出方法
寫出位元組資料的方法:
public void write(byte[] bytes):寫出所有位元組陣列中的位元組
public void write(byte[] bytes,int off,int len): 寫出位元組陣列的內容,從off索引開始的後面len個
public void write(int i): 寫出的是一個位元組
/*
public void write(byte[] bytes):寫出所有位元組陣列中的位元組
public void write(byte[] bytes,int off,int len): 寫出位元組陣列的內容,從off索引開始的後面len個
public void write(int i): 寫出的是一個位元組
 */
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1:創
        OutputStream os = new FileOutputStream("file12.txt", true);
        //2:寫
        byte[] bytes = "abc123".getBytes();
        //public void write(byte[] bytes):寫出所有位元組陣列中的位元組
        //os.write(bytes);

        //public void write(byte[] bytes,int off,int len):
        // 寫出位元組陣列的內容,從off索引開始的後面len個
        //os.write(bytes, 3, 3);

        //public void write(int i): 寫出的是一個位元組
        os.write(65);

        //3:關
        os.close();

    }

}
5.位元組輸出流寫出換行
windows:  \r\n
linux: \r
可以藉助System.lineSeparator()

String ls=System.lineSeparator(); //各種系統通用
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //windows:  \r\n
        //linux: \r
        //可以藉助System.lineSeparator()
        //String ls=System.lineSeparator(); //各種系統通用

        //1.創
        FileOutputStream fos = new FileOutputStream("file13.txt");
        //2.寫
        fos.write("窗前明月光".getBytes());
        fos.write("\r\n".getBytes());
        fos.write("疑是地上霜".getBytes());
        //String ls = System.lineSeparator();//換行符
        //fos.write(ls.getBytes());
        fos.write(System.lineSeparator().getBytes());
        fos.write("舉頭望明月".getBytes());

        //3.關
        fos.close();
    }
}

位元組流(輸入流)

1.位元組輸入流的使用

位元組輸入流的頂層父類是InputStream,是一個抽象類,這裡定義了所有位元組輸入流所要使用的方法。

使用時藉助其子類FileInputStream.

入門使用

1)創:建立輸入流物件==[需要關聯檔案]==

public FileInputStream(String file)
public FileInputStream(File file)

2)讀:呼叫read方法讀取資料

public int read():一次讀取一個位元組返回,如果沒有返回-1
public int read(byte[] bytes):一次讀取多個位元組放到陣列,返回有效讀取的個數,如果沒有返回-1

3)關:呼叫close方法關資源

public void close():關流

【程式碼實踐】

/*
位元組輸入流的基本使用:
 */
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1.創
        FileInputStream fis = new FileInputStream("file01.txt");
        //2.讀
        //int read()
        //傳統寫法:不會這麼去讀取
        //int r = fis.read();
        //System.out.println("r = " + r);
        //System.out.println(fis.read());//98
        //System.out.println(fis.read());//99
        //System.out.println(fis.read());//-1 //表示結束

        //優化寫法:以後就這麼寫
        int b;
        while ((b=fis.read())!=-1) {
            System.out.println(b);
        }


        //3.關
        fis.close();
    }
}
讀取資料的程式碼優化

位元組輸入流:
1)創
2)讀
3)關

/*
public int read(byte[] bytes):讀取多個資料到位元組陣列,返回有效讀取位元組個數,如果沒有讀取到位元組返回-1
 */
public class Demo02 {
    public static void main(String[] args) throws IOException {
        //1.創
        FileInputStream fis = new FileInputStream("file02.txt");
        //2.讀
        //寫法一:
        //byte[] bytes = new byte[3];
        //int len = fis.read(bytes);
        //System.out.println(len+":"+ Arrays.toString(bytes));//3:[97, 98, 99]
        //len = fis.read(bytes);
        //System.out.println(len+":"+ Arrays.toString(bytes));//1:[49, 98, 99]
        //len = fis.read(bytes);
        //System.out.println(len+":"+ Arrays.toString(bytes));//-1:[49, 98, 99]


        //寫法二:高效讀取
        byte[] bytes = new byte[10];
        int len;

        while ((len = fis.read(bytes)) != -1) {
            //String
            System.out.println(new String(bytes,0,len));
          //將位元組陣列中從0開始往後len個位元組資料變成字串
        }

        //3.關
        fis.close();

    }
}
2.檔案拷貝
需求:
完成 img1/美女.jpg  拷貝到  img2/beauty.jpg

思路:
藉助FileInputStream 讀取讀取資料到記憶體,然後藉助OutputStream寫出資料到目標檔案

步驟:
1)創:分別建立位元組輸入和輸出流物件
2)讀寫 : 邊讀邊寫
3)關 : 關流
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //完成 img1/美女.jpg  拷貝到  img2/beauty.jpg
        //1)創:分別建立位元組輸入和輸出流物件
        FileInputStream fis = new FileInputStream("img1/美女.jpg");
        FileOutputStream fos = new FileOutputStream("img2/beauty.jpg");
        //2)讀寫 : 邊讀邊寫

        //int b;//臨時儲存讀取的位元組
        //while ((b = fis.read()) != -1) {
        //    //將讀取的位元組,寫道檔案中
        //    fos.write(b);
        //}


        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }


        //3)關 : 關流
        fos.close();
        fis.close();
    }
}
3.位元組流讀取文字亂碼問題
使用位元組輸入流讀取中文:
位元組流不適合用來處理文字資料,字元流才適合用來處理文字資料
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1.創
        FileInputStream fis = new FileInputStream("file03.txt");
        //2.讀
        //int b;
        //while ((b = fis.read()) != -1) {
        //    System.out.println((char)b);
        //}

        byte[] bytes = new byte[2];
        int len;
        while ((len = fis.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, len));
        }

        //3.關
        fis.close();
    }
}

在這裡插入圖片描述

字元流(輸入流)

字元輸入流的使用

和位元組輸入流的操作一樣

Reader是一個抽象類,是字元輸入流的超類,定義了字元輸入流的相關方法。

實際使用時,用其子類FileReader

基本使用步驟

1)創

構造方法:
public FileReader(String path)
public FileReader(File path)

2)讀: 呼叫read方法讀取字元

public int read(): 一次讀取一個字元,如果讀取到最後沒有內容,返回-1
public int read(char[] chars): 一次讀取多個字元,返回有效讀取的字元個數,如果沒有內容了,返	回-1

3)關: 呼叫close

  public void close()
【程式碼實踐】
import java.io.FileReader;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1.創
        FileReader fr = new FileReader("file03.txt");
        //2.讀
        //int read():讀取一個字元,沒有字元返回-1

        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println((char) fr.read());
        //System.out.println( fr.read());//-1
        //System.out.println( fr.read());//-1

        // int c;
        // while ((c = fr.read()) != -1) {
        //     System.out.println((char) c);
        // }


        //int read(char[] cbuf):讀取多個字元到字元陣列,返回讀取有效個數,如果沒有返回-1
        char[] cbuf = new char[2];
        int len;
        while ((len = fr.read(cbuf)) != -1) {
            //讀取的有效字元變成字串
            System.out.println(new String(cbuf, 0, len));
        }


        //3.關
        fr.close();
    }
}

字元流(輸出流)

字元輸出流的使用

和位元組輸出流使用極其相似

字元輸出流的超類是Writer,是抽象類,裡面定義了一些字元輸出流通用的方法

    public void close(): 關流
    public void flush(): 重新整理
    public void write(int c) :寫出一個字元
    public void write(char[] chars) :一次寫出一個字元陣列
    public void write(char[] chars,int off, int len) :一次寫出一個字元陣列中指定的字元
    public void write(String str) :一次寫出一個字串
    public void write(String str,int off, int len)

真正使用時,使用的是其子類FileWriter

使用步驟

  1. 構造方法:

    //沒有拼接
    public FileWriter(String fileName)
    public FileWriter(File file)
    //有拼接,但是append要為true
    public FileWriter(String fileName , boolean append)
    public FileWriter(File file , boolean append)
    
  2. 寫:呼叫write方法

    public void write(int c) :寫出一個字元
    public void write(char[] chars) :一次寫出一個字元陣列
    public void write(char[] chars,int off, int len) :一次寫出一個字元陣列中指定的字元
    public void write(String str) :一次寫出一個字串
    public void write(String str,int off, int len)
    
  3. 關:呼叫close

    public void close(): 關流
    
程式碼實踐
/*
字元輸出流的基本使用
 */
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1.創
        //沒有拼接
        // FileWriter fw = new FileWriter("file04.txt");

        //拼接
        FileWriter fw = new FileWriter("file04.txt",true);
        //2.寫
        //write(int c)
        fw.write('A');
        //write(char[] chars)
        char[] chars = {'a', '1', '我'};
        fw.write(chars);
        //write(char[] chars,int off,int len)
        fw.write(chars,1,2);
        fw.write(System.lineSeparator());//換行
        //write(String str)
        fw.write("靜夜思");
        fw.write("\r\n");//換行
        //write(String str,int off,int len)
        fw.write("靜夜思",1,2);

        //3.關
        fw.close();

    }
}

關閉和重新整理的區別

關閉和重新整理

關閉:關流,把緩衝區的資料刷出【關流+重新整理】
public void close()
重新整理:把緩衝區的資料刷出到硬碟或者其他儲存介質【就是重新整理】
public void flush()
/*
關閉和重新整理的區別
關閉:close  關閉後不能繼續寫【重新整理+關閉資源】
重新整理:flush  重新整理後可以繼續寫【重新整理】
 */
public class Demo02 {
    public static void main(String[] args) throws IOException {
        //1.創
        FileWriter fw = new FileWriter("file05.txt");
        //2.寫
        fw.write("我愛香港!!");//將字元資料臨時儲存到緩衝區
        fw.flush();//將快取中的資料寫出到檔案中

        fw.write("一國兩制");
        fw.flush();
        //3.關
        fw.close();
        //fw.write("我愛祖國");
    }
}

字元流和位元組流的使用區別

字元流的使用場景:當處理純文字字元資料時,可以使用字元流

位元組流的使用場景:常處理位元組資料時的複製拷貝,可以使用位元組流: 比如,圖片,視訊,超文字檔案的處理

IO異常的處理

JDK7之前的處理方式:

try - catch - finnaly進行處理
關流的動作,需要放到finally中,如果存在多個流需要關閉,可以自定義一個專門用來關流的工具類
/*
try - catch - finnaly進行處理
關流的動作,需要放到finally中,如果存在多個流需要關閉,可以自定義一個專門用來關流的工具類
 */
public class Demo01 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //完成 img1/美女.jpg  拷貝到  img2/beauty.jpg
            //1)創:分別建立位元組輸入和輸出流物件
            fis = new FileInputStream("img1/美女.jpg");
            fos = new FileOutputStream("X:/img2/beauty.jpg");
            //2)讀寫 : 邊讀邊寫


            byte[] bytes = new byte[1024];
            int len;
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3)關 : 關流
            //CloseUtil.close(fos, fis);
            //CloseUtil.close(fos, fis);
            CloseUtil.close(fis,fos);


        }
    }
}

工具類

/*
關流工具類的優化
 */
public class CloseUtil {
    //杜絕其他類建立這個工具類的物件
    private CloseUtil(){}

    public static void close(AutoCloseable... resource) {
        for (AutoCloseable r : resource) {
            try {
                if (r != null)
                    r.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

JDK7 處理方式

優點就是可以自動關流,可以使用try-with-resource

【格式】

try (建立流物件語句,如果多個,使用';'隔開) {
   // 讀寫資料
} catch (IOException e) {
   e.printStackTrace();
}

【程式碼實踐】

/*
try-whit-resource:自動關流


 */
public class Demo02 {
    public static void main(String[] args) {

        //1)創:分別建立位元組輸入和輸出流物件
        try (FileInputStream fis = new FileInputStream("img1/美女.jpg");
             FileOutputStream fos = new FileOutputStream("img2/beauty.jpg")
        ) {

            //2)讀寫 : 邊讀邊寫

            byte[] bytes = new byte[1024];
            int len;
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

屬性集

屬性集使用

Properties: 屬性集 ,是HashTable的子類 HashTable又是Map介面的實現類,Properties內部儲存的資料,就是鍵值對。

基本方法使用

特有方法:
- public Object setProperty(String key, String value) : 儲存一對屬性。 【put】
- public String getProperty(String key) :使用此屬性列表中指定的鍵搜尋屬性值。【get】
- public Set<String> stringPropertyNames() :所有鍵的名稱的集合。 【keySet】

【程式碼實踐】

public class Demo01 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        //Object setProperty(String key, String value) : 儲存一對屬性。 【put】
        pro.setProperty("username", "root");
        pro.setProperty("password", "root");
        pro.setProperty("driverClass", "com.mysql.jdbc.Driver");
        pro.setProperty("url", "jdbc:mysql:///day01");

        System.out.println("pro = " + pro);

        //String getProperty(String key) :使用此屬性列表中指定的鍵搜尋屬性值。【get】
        //Object username = pro.get("username");
        String username = pro.getProperty("username");
        System.out.println("username = " + username);

        //Set<String> stringPropertyNames() :所有鍵的名稱的集合。 【keySet】
        Set<String> names = pro.stringPropertyNames();
        System.out.println("names = " + names);

    }
}

和流相關的方法

儲存屬性集中的鍵值對資訊到配置檔案
public void store(Writer write,String comments) : 
		write 是一個字元輸出流需要關聯一個檔案,comments是註釋
public void store(OutputStream out,String comments) :
		write 是一個字元輸出流需要關聯一個檔案,comments是註釋
//將記憶體中的Properties屬性資訊儲存到檔案中
//void store(Writer write,String comments) :write 是一個字元輸出流需要關聯一個檔案,comments是註釋
//void store(OutputStream out,String comments) :write 是一個字元輸出流需要關聯一個檔案,comments是註釋

try (FileWriter fileWriter = new FileWriter("mysql.properties");) {
    pro.store(fileWriter, "This is comments, 這是註釋");
} catch (IOException e) {
    e.printStackTrace();
}
如果要載入本地檔案的鍵值對資訊到Properties中
public void load(InputStream in):傳入的流目的就是關聯配置檔案
public void load(Reader in):傳入的流目的就是關聯配置檔案
public class Demo02 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        System.out.println("pro = " + pro);

        //void load(InputStream in):傳入的流目的就是關聯配置檔案
        //void load(Reader in):傳入的流目的就是關聯配置檔案
        try (FileReader reader = new FileReader("mysql.properties");) {
            pro.load(reader);//載入配置檔案中的屬性資訊到pro物件
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("pro = " + pro);

    }
}
tore(fileWriter, "This is comments, 這是註釋");
} catch (IOException e) {
    e.printStackTrace();
}
如果要載入本地檔案的鍵值對資訊到Properties中
public void load(InputStream in):傳入的流目的就是關聯配置檔案
public void load(Reader in):傳入的流目的就是關聯配置檔案
public class Demo02 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        System.out.println("pro = " + pro);

        //void load(InputStream in):傳入的流目的就是關聯配置檔案
        //void load(Reader in):傳入的流目的就是關聯配置檔案
        try (FileReader reader = new FileReader("mysql.properties");) {
            pro.load(reader);//載入配置檔案中的屬性資訊到pro物件
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("pro = " + pro);

    }
}

相關文章