那些年,菜丸被面試官逼瘋的IO流

那些年,菜丸被面試官逼瘋的IO流

首先我們需要知道什麼是流?

流就是一組有順序的,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。它的特性是進行數據傳輸。

接下來我們看看IO流的分類:

  1. 按流向分類:輸入流、輸出流
  2. 按操作對象分類:字節流、字符流
  3. 按功能分類:節點流、處理流

前方高能,坐下來請慢慢地聽我說!

一:字節流和字符流
字節流:InputStream 和OutputStream 是java中可以按照最小字節單位讀取的流,即每次讀寫一個字節,字節流是直接連接到輸入源的流。
字符流:是以字符爲單位進行數據處理的IO流。本質其實就是基於字節流讀取時,去查找指定的碼錶。

二:字節流與字符流之間的區別:

  1. 讀寫單位不同:字節流式以字節(8位2進制)爲單位,字符流是以字符爲單位,根據碼錶映射字符,一次可能讀多個字節。
  2. 處理對象不同:字節流能處理所有類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。
  3. 一次讀入或讀出是8位二進制。
  4. 字符流:一次讀入或讀出是16位二進制。

結論:

Out—>將輸出的字符流—>字節流—>用於輸出到控制檯 或者 文件
注意這個是寫====輸出的是來源,形容詞,不是你理解的字符輸出流轉字節輸出流



In—>將輸入的字節流—>字符流—>用於讀取到控制檯 或 內存
注意這個是讀====輸入的是來源,形容詞,不是你理解的字節輸入流轉字符輸入流

要麼字節流要麼字符流,具體再分哪種來源的流的話,就看是In還是Out了

  1. InputStreamReader看似是往裏寫(In),其實是往外讀(Reader)
  2. OutputStreamWriter看似是往外讀(Out),其實是往裏寫(Writer)

三:輸入流和輸出流的用途:

  1. 輸入流是指程序從數據源中讀取數據。只進行讀操作;
  2. 輸出流是指將數據從程序中寫到指定的文件中;

四:輸入流字節流InputStream與輸出字節流InputStream

  1. InputStream是一個抽象類,是所有輸入字節流的父類。
  2. ByteArrayInputStream、StringBufferInputStream、FileInputStream
    他們分別從數組、StringBuffer、和本地文件中讀取數據。
  3. PipedInputStream是從與其它線程共用的管道中讀取數據,與Piped 相關的知識後續單獨介紹。
  4. ObjectInputStream 和所有FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。
  5. OutputStream 是所有的輸出字節流的父類,它是一個抽象類。
  6. ByteArrayOutputStream、FileOutputStream 是兩種基本的介質流,它們分別向Byte數組、和本地文件中寫入數據。
  7. PipedOutputStream 是向與其它線程共用的管道中寫入數據。
  8. ObjectOutputStream 和所有FilterOutputStream 的子類都是裝飾流。

上代碼理解一下,此代碼使用緩衝數組的方法讀取文件內容,提高效率

public static void readArr() {
     // 1、明確源數據源
    File f = new File("F:/1/菜丸子/1.txt");
    // 2、構建流的對象
    InputStream ins = null;
     try {
         ins = new FileInputStream(f);
             // 3、聲明緩衝數組
         int i;// 表示讀取了多少個字符到數組中
          byte[] bt = new byte[5];// 字節緩衝數組
           // 4、讀取數據到數組中
           //可以讀多少寫多少,轉化成char類型,但是文件中都是英文,如果有中文則輸出亂碼
           while ((i = (ins.read(bt))) != -1) {
                  for (int j = 0; j < i; j++) {
                       System.out.print((char) bt[j]);
                     }
                 }
          } catch (Exception e) {
          e.printStackTrace();
          } finally {
           //關閉流
           try {
               if (ins != null) {
                 ins.close();
                  }
            } catch (Exception e) {
             e.printStackTrace();
         }
      }
 }

五:節點流和處理流的概念

節點流:直接與數據相連,進行數據的讀寫;

處理流:是指在節點流上套接了一層。

  • 常用的節點流
    1.文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件進行處理的節點流

import java.io.FileReader;
import java.io.FileWriter;
 /**
 *  使用FileRead、FileWriter複製文件
 *
 * @author  caiwan
 *
 */
public class TestFieldWriter {
public static void main(String []args){
  FileReader fr=null;
  FileWriter fw=null;
  try {
    fr=new FileReader("C:\\Users\\116060\\Desktop\\eeee.txt");//要讀取的文件
    fw=new FileWriter("C:\\Users\\116060\\Desktop\\ffff.txt");//要複製的目的文件
    int i=0;
    while((i=fr.read())!=-1){
      fw.write(i);
      System.out.println((char)i);//將得到的ASCII碼值轉換成字符型
    }
    fr.close();
    fw.close();
  } catch (Exception e) {
    // TODO: handle exception
  }
}
}

2.數 組 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 對數組進行處理的節點流(對應的不再是文件,而是內存中的一個數組)

3.字符串 :StringReader、 StringWriter 對字符串進行處理的節點流

4.管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 對管道進行處理的節點流

  • 常用的處理流

1.緩衝流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加緩衝功能,避免頻繁讀寫硬盤。


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
/**
 * 字符緩衝流(使用 BufferedReader 和 BufferedWriter)
 *
 * @author  caiwan
 *
 */
public class Demo2 {
     public static void main(String[] args) {
           // 1、指明源和目標
           File o = new File("F:/temp/java11.template");
           File t = new File("F:/temp/java11.txt");
           // 2、構建流的對象
           Reader re = null;
           Writer wt = null;
           BufferedReader bfr = null;
           BufferedWriter bfw = null;
           try {
                re = new FileReader(o);
                bfr = new BufferedReader(re);
                wt = new FileWriter(t);
                bfw = new BufferedWriter(wt);
                String msg = null;
                // 讀取操作
                while ((msg = bfr.readLine()) != null) {// 讀一行
                     // System.out.println(msg);
                     bfw.write(msg);
                     bfw.write("\r\n");// 執行換行,讀一行 寫一行 換行
                     // 或者 :bfw.newLine();//換行
                }
                bfw.flush();
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                // 關閉流
                try {
                     if (wt != null) {// 爲了避免空指針異常,進行判空
                           wt.close();
                     }
                     if (re != null) {
                           re.close();
                     }
                } catch (Exception e) {
                     e.printStackTrace();
                }
           }
     }
}

2.轉換流:InputStreamReader 、OutputStreamReader實現字節流和字符流之間的轉換。

3.數據流: DataInputStream 、DataOutputStream 等-提供將基礎數據類型寫入到文件中,或者讀取出來。

六:轉換流

InputStreamReader 、OutputStreamWriter 要InputStream或OutputStream作爲參數,實現從字節流到字符流的轉換。

七:常用例子

包裝流設置字符集的案例:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
/**
 * 包裝流設置字符集,使用InputStreamReader 和 OUtputStreamWriter:
 * @author caiwan
 */
public class Demo01 {
     public static void main(String[] args) {
           // 確定源和目標文件
           Scanner sc = new Scanner(System.in);
           File o = new File("kh/java48.template");
           File t = new File("kh/java48.txt");
           check(o);
           check(t);
           // 構建流對象
           InputStream ins = null;
           OutputStream outs = null;
           InputStreamReader insr = null;
           OutputStreamWriter outsw = null;
           try {
                outs = new FileOutputStream(o);// 先做爲目標文件寫入內容
                outsw = new OutputStreamWriter(outs, "UTF-8");//編碼格式爲UTF-8
                System.out.println("輸入你要寫入的內容:");
                String msg = sc.next();
                // 寫入內容
                outsw.write(msg);
                // 刷新
                outsw.flush();
                System.out.println("已經完全寫入!");
                ins = new FileInputStream(o);// 作爲源文件
                insr = new InputStreamReader(ins, "UTF-8");//編碼格式爲UTF-8
                outs = new FileOutputStream(t);// 作爲寫入的目標文件
                outsw = new OutputStreamWriter(outs, "UTF-8");//編碼格式爲UTF-8
                char[] ch = new char[1024];
                int i = 0;
                // 執行邊讀邊寫
                while ((i = insr.read(ch)) != -1) {
                     outsw.write(ch, 0, i);
                }
                // 刷新
                outsw.flush();
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                // 關閉流
                try {
                     if (outs != null) {
                           outs.close();
                     }
                     if (ins != null) {
                           ins.close();
                     }
                } catch (Exception e) {
                     e.printStackTrace();
                }
           }
     }
     public static void check(File file) {
           try {
                if (!file.exists()) {
                     file.getParentFile().mkdirs();// 創建文件夾
                     file.createNewFile();// 創建文件
                     System.out.println("沒有該文件!已創建成功!");
                }
           } catch (Exception e) {
                e.printStackTrace();
           }
     }
}

最後:

歡迎各位小夥伴關注我的公衆號:菜丸的程序屋。希望將我的不足之處給予指點,謝謝大家。喜歡Java,熱衷學習的小夥伴可以加我微信: CaiWan_Y
在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章