1.1為什么會(huì)出現(xiàn)字符流
-
字符流的介紹
由于字節(jié)流操作中文不是特別的方便表伦,所以Java就提供字符流
字符流 = 字節(jié)流 + 編碼表
-
中文的字節(jié)存儲(chǔ)方式
用字節(jié)流復(fù)制文本文件時(shí)敞斋,文本文件也會(huì)有中文,但是沒(méi)有問(wèn)題肯污,原因是最終底層操作會(huì)自動(dòng)進(jìn)行字節(jié)拼接成中文拇泣,如何識(shí)別是中文的呢?
漢字在存儲(chǔ)的時(shí)候改基,無(wú)論選擇哪種編碼存儲(chǔ),第一個(gè)字節(jié)都是負(fù)數(shù)
1.2編碼表
-
什么是字符集
是一個(gè)系統(tǒng)支持的所有字符的集合咖为,包括各國(guó)家文字秕狰、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)躁染、數(shù)字等
l計(jì)算機(jī)要準(zhǔn)確的存儲(chǔ)和識(shí)別各種字符集符號(hào)鸣哀,就需要進(jìn)行字符編碼,一套字符集必然至少有一套字符編碼吞彤。常見(jiàn)字符集有ASCII字符集我衬、GBXXX字符集叹放、Unicode字符集等
-
常見(jiàn)的字符集
-
ASCII字符集:
lASCII:是基于拉丁字母的一套電腦編碼系統(tǒng),用于顯示現(xiàn)代英語(yǔ)挠羔,主要包括控制字符(回車(chē)鍵井仰、退格、換行鍵等)和可顯示字符(英文大小寫(xiě)字符破加、阿拉伯?dāng)?shù)字和西文符號(hào))
基本的ASCII字符集俱恶,使用7位表示一個(gè)字符,共128字符范舀。ASCII的擴(kuò)展字符集使用8位表示一個(gè)字符合是,共256字符,方便支持歐洲常用字符锭环。是一個(gè)系統(tǒng)支持的所有字符的集合端仰,包括各國(guó)家文字、標(biāo)點(diǎn)符號(hào)田藐、圖形符號(hào)荔烧、數(shù)字等
-
GBXXX字符集:
GBK:最常用的中文碼表。是在GB2312標(biāo)準(zhǔn)基礎(chǔ)上的擴(kuò)展規(guī)范汽久,使用了雙字節(jié)編碼方案鹤竭,共收錄了21003個(gè)漢字,完全兼容GB2312標(biāo)準(zhǔn)景醇,同時(shí)支持繁體漢字以及日韓漢字等
-
Unicode字符集:
UTF-8編碼:可以用來(lái)表示Unicode標(biāo)準(zhǔn)中任意字符臀稚,它是電子郵件、網(wǎng)頁(yè)及其他存儲(chǔ)或傳送文字的應(yīng)用 中三痰,優(yōu)先采用的編碼吧寺。互聯(lián)網(wǎng)工程工作小組(IETF)要求所有互聯(lián)網(wǎng)協(xié)議都必須支持UTF-8編碼散劫。它使用一至四個(gè)字節(jié)為每個(gè)字符編碼
編碼規(guī)則:
128個(gè)US-ASCII字符稚机,只需一個(gè)字節(jié)編碼
拉丁文等字符,需要二個(gè)字節(jié)編碼
大部分常用字(含中文)获搏,使用三個(gè)字節(jié)編碼
其他極少使用的Unicode輔助字符赖条,使用四字節(jié)編碼
-
1.3字符串中的編碼解碼問(wèn)題
-
相關(guān)方法
方法名 說(shuō)明 byte[] getBytes() 使用平臺(tái)的默認(rèn)字符集將該 String編碼為一系列字節(jié) byte[] getBytes(String charsetName) 使用指定的字符集將該 String編碼為一系列字節(jié) String(byte[] bytes) 使用平臺(tái)的默認(rèn)字符集解碼指定的字節(jié)數(shù)組來(lái)創(chuàng)建字符串 String(byte[] bytes, String charsetName) 通過(guò)指定的字符集解碼指定的字節(jié)數(shù)組來(lái)創(chuàng)建字符串 代碼演示
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
//定義一個(gè)字符串
String s = "中國(guó)";
//byte[] bys = s.getBytes(); //[-28, -72, -83, -27, -101, -67]
//byte[] bys = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67]
byte[] bys = s.getBytes("GBK"); //[-42, -48, -71, -6]
System.out.println(Arrays.toString(bys));
//String ss = new String(bys);
//String ss = new String(bys,"UTF-8");
String ss = new String(bys,"GBK");
System.out.println(ss);
}
}
1.4字符流寫(xiě)數(shù)據(jù)
-
介紹
Writer: 用于寫(xiě)入字符流的抽象父類(lèi)
FileWriter: 用于寫(xiě)入字符流的常用子類(lèi)
-
構(gòu)造方法
方法名 說(shuō)明 FileWriter(File file) 根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(File file, boolean append) 根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(String fileName) 根據(jù)給定的文件名構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(String fileName, boolean append) 根據(jù)給定的文件名以及指示是否附加寫(xiě)入數(shù)據(jù)的 boolean 值來(lái)構(gòu)造 FileWriter 對(duì)象 -
成員方法
方法名 說(shuō)明 void write(int c) 寫(xiě)一個(gè)字符 void write(char[] cbuf) 寫(xiě)入一個(gè)字符數(shù)組 void write(char[] cbuf, int off, int len) 寫(xiě)入字符數(shù)組的一部分 void write(String str) 寫(xiě)一個(gè)字符串 void write(String str, int off, int len) 寫(xiě)一個(gè)字符串的一部分 -
刷新和關(guān)閉的方法
方法名 說(shuō)明 flush() 刷新流,之后還可以繼續(xù)寫(xiě)數(shù)據(jù) close() 關(guān)閉流常熙,釋放資源纬乍,但是在關(guān)閉之前會(huì)先刷新流。一旦關(guān)閉裸卫,就不能再寫(xiě)數(shù)據(jù) 代碼演示
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("myCharStream\\a.txt");
//void write(int c):寫(xiě)一個(gè)字符
// fw.write(97);
// fw.write(98);
// fw.write(99);
//void writ(char[] cbuf):寫(xiě)入一個(gè)字符數(shù)組
char[] chs = {'a', 'b', 'c', 'd', 'e'};
// fw.write(chs);
//void write(char[] cbuf, int off, int len):寫(xiě)入字符數(shù)組的一部分
// fw.write(chs, 0, chs.length);
// fw.write(chs, 1, 3);
//void write(String str):寫(xiě)一個(gè)字符串
// fw.write("abcde");
//void write(String str, int off, int len):寫(xiě)一個(gè)字符串的一部分
// fw.write("abcde", 0, "abcde".length());
fw.write("abcde", 1, 3);
//釋放資源
fw.close();
}
}
1.5字符流讀數(shù)據(jù)
-
介紹
Reader: 用于讀取字符流的抽象父類(lèi)
FileReader: 用于讀取字符流的常用子類(lèi)
-
構(gòu)造方法
方法名 說(shuō)明 FileReader(File file) 在給定從中讀取數(shù)據(jù)的 File 的情況下創(chuàng)建一個(gè)新 FileReader FileReader(String fileName) 在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新 FileReader -
成員方法
方法名 說(shuō)明 int read() 一次讀一個(gè)字符數(shù)據(jù) int read(char[] cbuf) 一次讀一個(gè)字符數(shù)組數(shù)據(jù) 代碼演示
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("myCharStream\\b.txt");
//int read():一次讀一個(gè)字符數(shù)據(jù)
// int ch;
// while ((ch=fr.read())!=-1) {
// System.out.print((char)ch);
// }
//int read(char[] cbuf):一次讀一個(gè)字符數(shù)組數(shù)據(jù)
char[] chs = new char[1024];
int len;
while ((len = fr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
//釋放資源
fr.close();
}
}
1.6字符流用戶(hù)注冊(cè)案例
-
案例需求
將鍵盤(pán)錄入的用戶(hù)名和密碼保存到本地實(shí)現(xiàn)永久化存儲(chǔ)
-
實(shí)現(xiàn)步驟
獲取用戶(hù)輸入的用戶(hù)名和密碼
將用戶(hù)輸入的用戶(hù)名和密碼寫(xiě)入到本地文件中
關(guān)流,釋放資源
代碼實(shí)現(xiàn)
public class CharStreamDemo8 {
public static void main(String[] args) throws IOException {
//需求: 將鍵盤(pán)錄入的用戶(hù)名和密碼保存到本地實(shí)現(xiàn)永久化存儲(chǔ)
//要求:用戶(hù)名獨(dú)占一行仿贬,密碼獨(dú)占一行
//分析:
//1,實(shí)現(xiàn)鍵盤(pán)錄入墓贿,把用戶(hù)名和密碼錄入進(jìn)來(lái)
Scanner sc = new Scanner(System.in);
System.out.println("請(qǐng)錄入用戶(hù)名");
String username = sc.next();
System.out.println("請(qǐng)錄入密碼");
String password = sc.next();
//2.分別把用戶(hù)名和密碼寫(xiě)到本地文件茧泪。
FileWriter fw = new FileWriter("charstream\\a.txt");
//將用戶(hù)名和密碼寫(xiě)到文件中
fw.write(username);
//表示寫(xiě)出一個(gè)回車(chē)換行符 windows \r\n MacOS \r Linux \n
fw.write("\r\n");
fw.write(password);
//刷新流
fw.flush();
//3.關(guān)流,釋放資源
fw.close();
}
}
1.7字符緩沖流
-
字符緩沖流介紹
BufferedWriter:將文本寫(xiě)入字符輸出流退个,緩沖字符,以提供單個(gè)字符调炬,數(shù)組和字符串的高效寫(xiě)入,可以指定緩沖區(qū)大小舱馅,或者可以接受默認(rèn)大小缰泡。默認(rèn)值足夠大,可用于大多數(shù)用途
BufferedReader:從字符輸入流讀取文本代嗤,緩沖字符棘钞,以提供字符,數(shù)組和行的高效讀取干毅,可以指定緩沖區(qū)大小宜猜,或者可以使用默認(rèn)大小。 默認(rèn)值足夠大硝逢,可用于大多數(shù)用途
-
構(gòu)造方法
方法名 說(shuō)明 BufferedWriter(Writer out) 創(chuàng)建字符緩沖輸出流對(duì)象 BufferedReader(Reader in) 創(chuàng)建字符緩沖輸入流對(duì)象 代碼演示
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
//BufferedWriter(Writer out)
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
bw.write("hello\r\n");
bw.write("world\r\n");
bw.close();
//BufferedReader(Reader in)
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
//一次讀取一個(gè)字符數(shù)據(jù)
// int ch;
// while ((ch=br.read())!=-1) {
// System.out.print((char)ch);
// }
//一次讀取一個(gè)字符數(shù)組數(shù)據(jù)
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
br.close();
}
}
1.8字符緩沖流特有功能
-
方法介紹
BufferedWriter:
方法名 說(shuō)明 void newLine() 寫(xiě)一行行分隔符姨拥,行分隔符字符串由系統(tǒng)屬性定義 BufferedReader:
方法名 說(shuō)明 String readLine() 讀一行文字。 結(jié)果包含行的內(nèi)容的字符串渠鸽,不包括任何行終止字符如果流的結(jié)尾已經(jīng)到達(dá)叫乌,則為null 代碼演示
public class BufferedStreamDemo02 {
public static void main(String[] args) throws IOException {
//創(chuàng)建字符緩沖輸出流
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
//寫(xiě)數(shù)據(jù)
for (int i = 0; i < 10; i++) {
bw.write("hello" + i);
//bw.write("\r\n");
bw.newLine();
bw.flush();
}
//釋放資源
bw.close();
//創(chuàng)建字符緩沖輸入流
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
String line;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
}
}
1.9字符緩沖流操作文件中數(shù)據(jù)排序案例
-
案例需求
使用字符緩沖流讀取文件中的數(shù)據(jù),排序后再次寫(xiě)到本地文件
-
實(shí)現(xiàn)步驟
將文件中的數(shù)據(jù)讀取到程序中
對(duì)讀取到的數(shù)據(jù)進(jìn)行處理
將處理后的數(shù)據(jù)添加到集合中
對(duì)集合中的數(shù)據(jù)進(jìn)行排序
將排序后的集合中的數(shù)據(jù)寫(xiě)入到文件中
代碼實(shí)現(xiàn)
public class CharStreamDemo14 {
public static void main(String[] args) throws IOException {
//需求:讀取文件中的數(shù)據(jù)徽缚,排序后再次寫(xiě)到本地文件
//分析:
//1.要把文件中的數(shù)據(jù)讀取進(jìn)來(lái)憨奸。
BufferedReader br = new BufferedReader(new FileReader("charstream\\sort.txt"));
//輸出流一定不能寫(xiě)在這里,因?yàn)闀?huì)清空文件中的內(nèi)容
//BufferedWriter bw = new BufferedWriter(new FileWriter("charstream\\sort.txt"));
String line = br.readLine();
System.out.println("讀取到的數(shù)據(jù)為" + line);
br.close();
//2.按照空格進(jìn)行切割
String[] split = line.split(" ");//9 1 2 5 3 10 4 6 7 8
//3.把字符串類(lèi)型的數(shù)組變成int類(lèi)型
int [] arr = new int[split.length];
//遍歷split數(shù)組凿试,可以進(jìn)行類(lèi)型轉(zhuǎn)換排宰。
for (int i = 0; i < split.length; i++) {
String smallStr = split[i];
//類(lèi)型轉(zhuǎn)換
int number = Integer.parseInt(smallStr);
//把轉(zhuǎn)換后的結(jié)果存入到arr中
arr[i] = number;
}
//4.排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//5.把排序之后結(jié)果寫(xiě)回到本地 1 2 3 4...
BufferedWriter bw = new BufferedWriter(new FileWriter("charstream\\sort.txt"));
//寫(xiě)出
for (int i = 0; i < arr.length; i++) {
bw.write(arr[i] + " ");
bw.flush();
}
//釋放資源
bw.close();
}
}