首頁  >  文章  >  Java  >  Java字元流實例分析

Java字元流實例分析

王林
王林轉載
2023-04-28 16:40:071104瀏覽

    一、字元流的由來

    由於使用位元組流操控中文時不是很方便,Java就提供了字元流來進行操控中文

    實作原理:位元組流編碼表

    為什麼用位元組流進行複製帶有中文的文字檔時沒有問題?

    因為底層操作會自動進行位元組拼接成中文

    怎麼辨識該位元組是中文呢?

    漢字在儲存時,無論是UTF-8或GBK,第一個位元組都是負數用來提示

    二、編碼表

    字元集:

    是一個系統支援的所有字符的集合,包括國家文字、標點符號、圖形符號、數字等

    計算機要準確的存儲和識別各種字符集符號,就需要進行字符編碼,一套字元集必然至少有一套字元編碼

    常見的字元集有ASCII字元集、GBXXX字元集、Unicode字元集等

    GBK:最常用的中文碼表,是在GB2312標準基礎上的擴展規範,使用了雙字節編碼方案,共收錄了21003個漢字,完全兼容GB2312標準,同時支持繁體漢字以及日韓漢字等

    GB18030:最新的中文碼表,收錄漢字70244個,採用多位元組編碼,每個字可以由1個、2個或4個位元組組成。支持中國少數民族的文字,同時支持繁體漢字以及日韓漢字等

    Unicode字符集:

    為了表達任意語言的任意字符而設計,是業界的一個標準,也稱為統一碼、標準萬國碼;它最多使用4個位元組的數字來表達每個字母、符號,或文字。有三種編碼方案:UTF-8、UTF-16、UTF32,最常用的是UTF-8

    UTF-8:可以用來表示Unicode標準中的任意字符,它是電子郵件、網頁及其他儲存或傳送文件的應用中,優先採用的編碼。網路工作小組要求所有的網際網路協定都必須支援UTF-8編碼格式。它使用一到四個位元組為每個字符編碼

    UTF-8編碼規則:

    128個US-ASCII字符,只需要一個位元組編碼

    拉丁文等字符,需要兩個字節編碼

    大部分常用字(含中文),使用三個字節編碼

    其他極少使用的UniCode輔助字符,使用四個字節編碼

    總結:編碼時使用那種規則,解碼就需要採用對應的規則,否則會亂碼

    三、字串中的編碼解碼問題

    編碼方法(IDEA):

    byte[] getBytes():使用平台預設的字元集將該String編碼為一系列字節,將結果儲存到新的位元組數組中

    # byte[] getBytes(String charsetName):使用指定的字元集將String編碼為一系列字節,將結果儲存到新的位元組數組中

    解碼方法(IDEA):

    String(byte[]bytes):透過使用平台的預設字元集解碼指定的位元組數組來建構新的String

    String(byte[]bytes,String charsetName):透過指定的字元集解碼指定的位元組數組來建構新的String

    IDEA中預設的編碼格式是UTF-8

    四、字元流的編碼解碼問題

    字元流抽象基底類別:

    Reader:字元輸入流的抽象類別

    Writer:字元輸出流的抽象類別

    字元流中和編碼解碼問題相關的兩個類別:

    InputStreamReader:是從位元組流到字元流的橋樑:它讀取字節,並使用指定的字元集將其解碼為字元。它使用的字元集可以由名稱指定,也可以被明確指定,或者可以接受平台的預設字元集

    建構方法:

    InputStreamReader( InputStream in)     建立一個使用預設字元集的InputStreamReader。
    InputStreamReader(InputStream in, String charsetName) 建立一個使用命名字元集的InputStreamReader。

    OutputStreamWruter:是從字元流到位元組流的橋樑:使用自訂的字元集將寫入的字元編碼為位元組,它使用的字元集可以由名稱指定,也可以明確指定,或可以接受平台的預設字元集

    建構方法:

    OutputStreamWriter(OutputStream out)     #建立一個使用預設字元編碼的OutputStreamWriter。
    OutputStreamWriter(OutputStream out, String charsetName) 建立一個使用命名字元集的OutputStreamWriter。
    public class ConversionStreamDemo {
        public static void main(String[] args) throws IOException {
            //创建一个默认编码格式的InputStreamReader\OutputStreamWriter
            InputStreamReader ipsr = new InputStreamReader(new FileInputStream("E:\\abc.txt"));
            OutputStreamWriter opsw = new OutputStreamWriter(new FileOutputStream("E:\\abc.txt"));
            //写入数据
            opsw.write("你好啊");
            opsw.close();
            //读数据,方式一:一次读取一个字节数据
            int ch;
            while ((ch = ipsr.read()) != -1) {
                System.out.print((char) ch);
            }
            ipsr.close();
    
        }
    }

    四、字符流写数据的五种方法

    方法名 说明
    void write(int c)     写一个字符
    void write(char[] cbuf) 写入一个字符数组
    void write(char[] cbuf,int off,int len) 写入字符数组的一部分
    void write(String str) 写入一个字符串
    void write(String str,int off,int len) 写入一个字符串的一部分

    字符流写数据需要注意缓冲区的问题,如果想要将缓冲区的数据加载出来需要在写入方法后加上刷新方法flush();

    前三个方法与字节流写入方法使用相同,这里重点介绍下面两种方式

    public class OutputStreamWriterDemo {
        public static void main(String[] args) throws IOException {
            //创建一个默认编码格式的OutputStreamWriter对象
            OutputStreamWriter opsw=new OutputStreamWriter(new FileOutputStream("E:\\abc.txt"));
            //方式一:写入一个字节
            opsw.write(97);
            opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法
            //方式二:写入一个字符数组
            char[]ch={'a','b','c','二'};
            opsw.write(ch);
            opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法
            //方式三:写入一个字符数组的一部分
            opsw.write(ch,0,2);
            opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法
            //方式四:写入一个字符串
            opsw.write("一二三");
            opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法
            //方式五:写入一个字符串的一部分
            opsw.write("三四五",1,2);
            opsw.flush();//如果需要在文件中立即显示输入的数据,就需要加入刷新方法
        }
    }

    五、字符流读数据的两种方法

    方法名 说明
    int read()     一次读取一个字符数据
    int read(char[] cbuf) 一次读取一个字符数组数据
    public class InputStreamReadDemo {
        public static void main(String[] args) throws IOException {
            //创建一个默认编码格式的InputStreamReader
            InputStreamReader ipsr=new InputStreamReader(new FileInputStream("E:\\abc.txt"));
            //读取数据,方式一一次读取一个字符数据
            int ch;
            while ((ch=ipsr.read())!=-1){
                System.out.print((char) ch);
            }
            ipsr.close();
            //方式二:一次读取一个字符数组数据
            char []ch=new char[1024];
            int len;
            while ((len=ipsr.read(ch))!=-1){
                System.out.print(new String(ch,0,len));
            }
            ipsr.close();
        }
    }

    小结:如果使用默认编码格式的话,那么字符输入流InputStreamReader可以使用子类FileReader来替代,字符输出流OutputStreamWriter可以使用其子类FileWriter来替代,两者在使用默认编码格式的情况下作用一致。

    以上是Java字元流實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除