Java?超詳細(xì)講解字符流
一、字符流的由來(lái)
由于使用字節(jié)流操控中文時(shí)不是很方便,Java就提供了字符流來(lái)進(jìn)行操控中文
實(shí)現(xiàn)原理:字節(jié)流+編碼表
為什么用字節(jié)流進(jìn)行復(fù)制帶有中文的文本文件時(shí)沒(méi)有問(wèn)題?
因?yàn)榈讓硬僮鲿?huì)自動(dòng)進(jìn)行字節(jié)拼接成中文
怎樣識(shí)別該字節(jié)是中文呢?
漢字在存儲(chǔ)時(shí),無(wú)論是UTF-8還是GBK,第一個(gè)字節(jié)都是負(fù)數(shù)用來(lái)提示
二、編碼表
字符集:
是一個(gè)系統(tǒng)支持的所有字符的集合,包括國(guó)家文字、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)、數(shù)字等
計(jì)算機(jī)要準(zhǔn)確的存儲(chǔ)和識(shí)別各種字符集符號(hào),就需要進(jìn)行字符編碼,一套字符集必然至少有一套字符編碼
常見(jiàn)的字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
GBK:最常用的中文碼表,是在GB2312標(biāo)準(zhǔn)基礎(chǔ)上的擴(kuò)展規(guī)范,使用了雙字節(jié)編碼方案,共收錄了21003個(gè)漢字,完全兼容GB2312標(biāo)準(zhǔn),同時(shí)支持繁體漢字以及日韓漢字等
GB18030:最新的中文碼表,收錄漢字70244個(gè),采用多字節(jié)編碼,每個(gè)字可以由1個(gè)、2個(gè)或4個(gè)字節(jié)組成。支持中國(guó)少數(shù)民族的文字,同時(shí)支持繁體漢字以及日韓漢字等
Unicode字符集:
為了表達(dá)任意語(yǔ)言的任意字符而設(shè)計(jì),是業(yè)界的一個(gè)標(biāo)準(zhǔn),也稱為統(tǒng)一碼、標(biāo)準(zhǔn)萬(wàn)國(guó)碼;它最多使用4個(gè)字節(jié)的數(shù)字來(lái)表達(dá)每個(gè)字母、符號(hào),或者文字。有三種編碼方案:UTF-8、UTF-16、UTF32,最常用的是UTF-8
UTF-8:可以用來(lái)表示Unicode標(biāo)準(zhǔn)中的任意字符,它是電子郵件、網(wǎng)頁(yè)及其他存儲(chǔ)或傳送文件的應(yīng)用中,優(yōu)先采用的編碼?;ヂ?lián)網(wǎng)工作小組要求所有的互聯(lián)網(wǎng)協(xié)議都必須支持UTF-8編碼格式。它使用一至四個(gè)字節(jié)為每個(gè)字符編碼
UTF-8編碼規(guī)則:
128個(gè)US-ASCII字符,只需要一個(gè)字節(jié)編碼
拉丁文等字符,需要兩個(gè)字節(jié)編碼
大部分常用字(含中文),使用三個(gè)字節(jié)編碼
其他極少使用的UniCode輔助字符,使用四個(gè)字節(jié)編碼
總結(jié):編碼時(shí)使用那種規(guī)則,解碼就需要采用對(duì)應(yīng)的規(guī)則,否則會(huì)亂碼
三、字符串中的編碼解碼問(wèn)題
編碼方法(IDEA):
byte[] getBytes():使用平臺(tái)默認(rèn)的字符集將該String編碼為一系列字節(jié),將結(jié)果存儲(chǔ)到新的字節(jié)數(shù)組中
byte[] getBytes(String charsetName):使用指定的字符集將該String編碼為一系列字節(jié),將結(jié)果存儲(chǔ)到新的字節(jié)數(shù)組中
解碼方法(IDEA):
String(byte[]bytes):通過(guò)使用平臺(tái)的默認(rèn)字符集解碼指定的字節(jié)數(shù)組來(lái)構(gòu)造新的String
String(byte[]bytes,String charsetName):通過(guò)指定的字符集解碼指定的字節(jié)數(shù)組來(lái)構(gòu)造新的String
IDEA中默認(rèn)的編碼格式是UTF-8
四、字符流的編碼解碼問(wèn)題
字符流抽象基類:
Reader:字符輸入流的抽象類
Writer:字符輸出流的抽象類
字符流中和編碼解碼問(wèn)題相關(guān)的兩個(gè)類:
InputStreamReader:是從字節(jié)流到字符流的橋梁:它讀取字節(jié),并使用指定的字符集將其解碼為字符。它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺(tái)的默認(rèn)字符集
構(gòu)造方法:
| InputStreamReader(InputStream in) | 創(chuàng)建一個(gè)使用默認(rèn)字符集的InputStreamReader。 |
| InputStreamReader(InputStream in, String charsetName) | 創(chuàng)建一個(gè)使用命名字符集的InputStreamReader。 |
OutputStreamWruter:是從字符流到字節(jié)流的橋梁:使用自訂的字符集將寫入的字符編碼為字節(jié),它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺(tái)的默認(rèn)字符集
構(gòu)造方法:
| OutputStreamWriter(OutputStream out) | 創(chuàng)建一個(gè)使用默認(rèn)字符編碼的OutputStreamWriter。 |
| OutputStreamWriter(OutputStream out, String charsetName) | 創(chuàng)建一個(gè)使用命名字符集的OutputStreamWriter。 |
public class ConversionStreamDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建一個(gè)默認(rèn)編碼格式的InputStreamReader\OutputStreamWriter
InputStreamReader ipsr = new InputStreamReader(new FileInputStream("E:\\abc.txt"));
OutputStreamWriter opsw = new OutputStreamWriter(new FileOutputStream("E:\\abc.txt"));
//寫入數(shù)據(jù)
opsw.write("你好啊");
opsw.close();
//讀數(shù)據(jù),方式一:一次讀取一個(gè)字節(jié)數(shù)據(jù)
int ch;
while ((ch = ipsr.read()) != -1) {
System.out.print((char) ch);
}
ipsr.close();
?
}
}
四、字符流寫數(shù)據(jù)的五種方法
| 方法名 | 說(shuō)明 |
| void write(int c) | 寫一個(gè)字符 |
| void write(char[] cbuf) | 寫入一個(gè)字符數(shù)組 |
| void write(char[] cbuf,int off,int len) | 寫入字符數(shù)組的一部分 |
| void write(String str) | 寫入一個(gè)字符串 |
| void write(String str,int off,int len) | 寫入一個(gè)字符串的一部分 |
字符流寫數(shù)據(jù)需要注意緩沖區(qū)的問(wèn)題,如果想要將緩沖區(qū)的數(shù)據(jù)加載出來(lái)需要在寫入方法后加上刷新方法flush();
前三個(gè)方法與字節(jié)流寫入方法使用相同,這里重點(diǎn)介紹下面兩種方式
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建一個(gè)默認(rèn)編碼格式的OutputStreamWriter對(duì)象
OutputStreamWriter opsw=new OutputStreamWriter(new FileOutputStream("E:\\abc.txt"));
//方式一:寫入一個(gè)字節(jié)
opsw.write(97);
opsw.flush();//如果需要在文件中立即顯示輸入的數(shù)據(jù),就需要加入刷新方法
//方式二:寫入一個(gè)字符數(shù)組
char[]ch={'a','b','c','二'};
opsw.write(ch);
opsw.flush();//如果需要在文件中立即顯示輸入的數(shù)據(jù),就需要加入刷新方法
//方式三:寫入一個(gè)字符數(shù)組的一部分
opsw.write(ch,0,2);
opsw.flush();//如果需要在文件中立即顯示輸入的數(shù)據(jù),就需要加入刷新方法
//方式四:寫入一個(gè)字符串
opsw.write("一二三");
opsw.flush();//如果需要在文件中立即顯示輸入的數(shù)據(jù),就需要加入刷新方法
//方式五:寫入一個(gè)字符串的一部分
opsw.write("三四五",1,2);
opsw.flush();//如果需要在文件中立即顯示輸入的數(shù)據(jù),就需要加入刷新方法
}
}
五、字符流讀數(shù)據(jù)的兩種方法
| 方法名 | 說(shuō)明 |
| int read() | 一次讀取一個(gè)字符數(shù)據(jù) |
| int read(char[] cbuf) | 一次讀取一個(gè)字符數(shù)組數(shù)據(jù) |
public class InputStreamReadDemo {
public static void main(String[] args) throws IOException {
//創(chuàng)建一個(gè)默認(rèn)編碼格式的InputStreamReader
InputStreamReader ipsr=new InputStreamReader(new FileInputStream("E:\\abc.txt"));
//讀取數(shù)據(jù),方式一一次讀取一個(gè)字符數(shù)據(jù)
int ch;
while ((ch=ipsr.read())!=-1){
System.out.print((char) ch);
}
ipsr.close();
//方式二:一次讀取一個(gè)字符數(shù)組數(shù)據(jù)
char []ch=new char[1024];
int len;
while ((len=ipsr.read(ch))!=-1){
System.out.print(new String(ch,0,len));
}
ipsr.close();
}
}
小結(jié):如果使用默認(rèn)編碼格式的話,那么字符輸入流InputStreamReader可以使用子類FileReader來(lái)替代,字符輸出流OutputStreamWriter可以使用其子類FileWriter來(lái)替代,兩者在使用默認(rèn)編碼格式的情況下作用一致。
到此這篇關(guān)于Java 超詳細(xì)講解字符流的文章就介紹到這了,更多相關(guān)Java 字符流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot?整合Mybatis-Plus并輸出SQL日志示例詳解
這篇文章主要介紹了SpringBoot整合Mybatis-Plus并輸出SQL日志,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
SpringBoot Jackson日期格式化統(tǒng)一配置的實(shí)現(xiàn)
Spring項(xiàng)目中經(jīng)常需要配置日期時(shí)間格式格式,本文主要介紹了SpringBoot Jackson日期格式化統(tǒng)一配置的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
解決IDEA導(dǎo)入javaWeb項(xiàng)目注解爆紅的問(wèn)題
這篇文章主要介紹了解決IDEA導(dǎo)入javaWeb項(xiàng)目注解爆紅的問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
java中Lambda常用場(chǎng)景代碼實(shí)例
這篇文章主要介紹了java中Lambda常用場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
maven配置多個(gè)鏡像的實(shí)現(xiàn)方法
這篇文章主要介紹了maven配置多個(gè)鏡像的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Java實(shí)現(xiàn)Excel表單控件的添加與刪除
本文通過(guò)Java代碼示例介紹如何在Excel表格中添加表單控件,包括文本框、單選按鈕、復(fù)選框、組合框、微調(diào)按鈕等,以及如何刪除Excel中的指定表單控件,需要的可以參考一下2022-05-05
JAVA應(yīng)用系統(tǒng)工具快捷托盤實(shí)例代碼
JAVA應(yīng)用系統(tǒng)工具快捷托盤實(shí)例代碼,需要的朋友可以參考一下2013-02-02
IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法
這篇文章主要介紹了IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04

