IO流(二)————字元流
阿新 • • 發佈:2019-01-30
1. 字元流FileReader
* 1.字元流是什麼
* 字元流是可以直接讀寫字元的IO流
* 字元流讀取字元, 就要先讀取到位元組資料, 然後轉為字元. 如果要寫出字元, 需要把字元轉為位元組再寫出.
* 2.FileReader
* FileReader類的read()方法可以按照字元大小讀取
*
* FileWriter類的write()方法可以自動把字元轉為位元組寫出
* 字元流也可以拷貝文字檔案, 但不推薦使用. 因為讀取時會把位元組轉為字元, 寫出時還要把字元轉回位元組.
* 程式需要讀取一段文字, 或者需要寫出一段文字的時候可以使用字元流
* 讀取的時候是按照字元的大小讀取的,不會出現半個中文
* 寫出的時候可以直接將字串寫出,不用轉換為位元組陣列
5. 字元流是否可以拷貝非純文字的檔案
* 不可以拷貝非純文字的檔案
* 因為在讀的時候會將位元組轉換為字元,在轉換過程中,可能找不到對應的字元,就會用?代替,寫出的時候會將字元轉換成位元組寫出去
* 如果是?,直接寫出,這樣寫出之後的檔案就亂了,看不了了
//字元流不能拷貝純文字的檔案
* BufferedReader的read()方法讀取字元時會一次讀取若干字元到緩衝區, 然後逐個返回給程式, 降低讀取檔案的次數, 提高效率
* BufferedWriter的write()方法寫出字元時會先寫到緩衝區, 緩衝區寫滿時才會寫到檔案, 降低寫檔案的次數, 提高效率
* BufferedReader的readLine()方法可以讀取一行字元(不包含換行符號)
* BufferedWriter的newLine()可以輸出一個跨平臺的換行符號"\r\n"
*
* 將一個文字文件上的文字反轉,第一行和倒數第一行交換,第二行和倒數第二行交換
* LineNumberReader是BufferedReader的子類, 具有相同的功能, 並且可以統計行號
* 呼叫getLineNumber()方法可以獲取當前行號
* 呼叫setLineNumber()方法可以設定當前行號
*
* FileReader是使用預設碼錶讀取檔案, 如果需要使用指定碼錶讀取, 那麼可以使用InputStreamReader(位元組流,編碼表)
* FileWriter是使用預設碼錶寫出檔案, 如果需要使用指定碼錶寫出, 那麼可以使用OutputStreamWriter(位元組流,編碼表)
* 畫圖分析轉換流
14. 獲取文字上字元出現的次數
* 獲取一個文字上每個字元出現的次數,將結果寫在times.txt上
15. 試用版軟體
* 當我們下載一個試用版軟體,沒有購買正版的時候,每執行一次就會提醒我們還有多少次使用機會用學過的IO流知識,模擬試用版軟體,試用10次機會,執行一次就提示一次您還有幾次機會,如果次數到了提示請購買正版
* 1.字元流是什麼
* 字元流是可以直接讀寫字元的IO流
* 字元流讀取字元, 就要先讀取到位元組資料, 然後轉為字元. 如果要寫出字元, 需要把字元轉為位元組再寫出.
* 2.FileReader
* FileReader類的read()方法可以按照字元大小讀取
*
2. 字元流FileWriterFileReader fr = new FileReader("aaa.txt"); //建立輸入流物件,關聯aaa.txt int ch; while((ch = fr.read()) != -1) { //將讀到的字元賦值給ch //通過專案預設的碼錶一次讀取一個字元 System.out.println((char)ch); //將讀到的字元強轉後列印 } fr.close(); //關流
* FileWriter類的write()方法可以自動把字元轉為位元組寫出
FileWriter fw = new FileWriter("aaa.txt");
fw.write("aaa");
fw.close();
3. 字元流的拷貝4. 什麼情況下使用字元流FileReader fr = new FileReader("a.txt"); FileWriter fw = new FileWriter("b.txt"); int ch; while((ch = fr.read()) != -1) { fw.write(ch); } fr.close(); fw.close();//Writer類中有一個2k的小緩衝區,如果不關流,就會將內容寫到緩衝區裡,關流會將緩衝區內容重新整理,再關閉
* 字元流也可以拷貝文字檔案, 但不推薦使用. 因為讀取時會把位元組轉為字元, 寫出時還要把字元轉回位元組.
* 程式需要讀取一段文字, 或者需要寫出一段文字的時候可以使用字元流
* 讀取的時候是按照字元的大小讀取的,不會出現半個中文
* 寫出的時候可以直接將字串寫出,不用轉換為位元組陣列
5. 字元流是否可以拷貝非純文字的檔案
* 不可以拷貝非純文字的檔案
* 因為在讀的時候會將位元組轉換為字元,在轉換過程中,可能找不到對應的字元,就會用?代替,寫出的時候會將字元轉換成位元組寫出去
* 如果是?,直接寫出,這樣寫出之後的檔案就亂了,看不了了
//字元流不能拷貝純文字的檔案
6. 自定義字元陣列的拷貝FileReader fr = new FileReader("雙元.jpg"); FileWriter fw = new FileWriter("copy.jpg"); int c; while((c = fr.read()) != -1) { fw.write(c); } fr.close(); fw.close();
FileReader fr = new FileReader("aaa.txt"); //建立字元輸入流,關聯aaa.txt
FileWriter fw = new FileWriter("bbb.txt"); //建立字元輸出流,關聯bbb.txt
int len;
char[] arr = new char[1024*8]; //建立字元陣列
while((len = fr.read(arr)) != -1) { //將資料讀到字元陣列中
fw.write(arr, 0, len); //從字元陣列將資料寫到檔案上
}
fr.close(); //關流釋放資源
fw.close();
7. 帶緩衝的字元流* BufferedReader的read()方法讀取字元時會一次讀取若干字元到緩衝區, 然後逐個返回給程式, 降低讀取檔案的次數, 提高效率
* BufferedWriter的write()方法寫出字元時會先寫到緩衝區, 緩衝區寫滿時才會寫到檔案, 降低寫檔案的次數, 提高效率
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); //建立字元輸入流物件,關聯aaa.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //建立字元輸出流物件,關聯bbb.txt
int ch;
while((ch = br.read()) != -1) { //read一次,會先將緩衝區讀滿,從緩衝去中一個一個的返給臨時變數ch
bw.write(ch); //write一次,是將資料裝到字元陣列,裝滿後再一起寫出去
}
br.close(); //關流
bw.close();
8. readLine()和newLine()方法* BufferedReader的readLine()方法可以讀取一行字元(不包含換行符號)
* BufferedWriter的newLine()可以輸出一個跨平臺的換行符號"\r\n"
*
/**
* @param args
* 帶緩衝區的流中的特殊方法
* readLine()
* newLine();
*
* newLine()與\r\n的區別
* newLine()是跨平臺的方法
* \r\n只支援的是windows系統
* @throws IOException
*/
BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
String line;
while((line = br.readLine()) != null) {
bw.write(line);
//bw.write("\r\n"); //只支援windows系統
bw.newLine(); //跨平臺的
}
br.close();
bw.close();
9. 將文字反轉* 將一個文字文件上的文字反轉,第一行和倒數第一行交換,第二行和倒數第二行交換
public class Test1 {
/**
* @param args
* 將一個文字文件上的文字反轉,第一行和倒數第一行交換,第二行和倒數第二行交換
*
* 分析:
* 1,建立輸入輸出流物件
* 2,建立集合物件
* 3,將讀到的資料儲存在集合中
* 4,倒著遍歷集合將資料寫到檔案上
* 5,關流
* @throws IOException
*
* 注意事項:
* 流物件儘量晚開早關
*/
public static void main(String[] args) throws IOException {
//改寫後是儘量晚開早關
// 1,建立輸入輸出流物件
BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
//2,建立集合物件
ArrayList<String> list = new ArrayList<>();
//3,將讀到的資料儲存在集合中
String line;
while((line = br.readLine()) != null) {
list.add(line);
}
br.close(); //關流
//4,倒著遍歷集合將資料寫到檔案上
BufferedWriter bw = new BufferedWriter(new FileWriter("revzzz.txt"));
for(int i = list.size() - 1; i >= 0; i--) {
bw.write(list.get(i));
bw.newLine();
}
//5,關流
bw.close();
}
}
10. LineNumberReader* LineNumberReader是BufferedReader的子類, 具有相同的功能, 並且可以統計行號
* 呼叫getLineNumber()方法可以獲取當前行號
* 呼叫setLineNumber()方法可以設定當前行號
*
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
String line;
lnr.setLineNumber(100); //設定行號
while((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + ":" + line);//獲取行號
}
lnr.close();
11. 裝飾設計模式 public class Demo6_Wrap {
/**
* @param args
* 裝飾設計模式的好處是:
* 耦合性不強,被裝飾的類的變化與裝飾類的變化無關
*/
public static void main(String[] args) {
HeiMaStudent hms = new HeiMaStudent(new Student());
hms.code();
}
}
interface Coder {
public void code();
}
class Student implements Coder {
@Override
public void code() {
System.out.println("javase");
System.out.println("javaweb");
}
}
class HeiMaStudent implements Coder {
//1,獲取被裝飾類的引用
private Student s; //獲取學生引用
//2,在構造方法中傳入被裝飾類的物件
public HeiMaStudent(Student s) {
this.s = s;
}
//3,對原有的功能進行升級
@Override
public void code() {
s.code();
System.out.println("ssh");
System.out.println("資料庫");
System.out.println("大資料");
System.out.println("...");
}
}
12. 使用指定的碼錶讀寫字元* FileReader是使用預設碼錶讀取檔案, 如果需要使用指定碼錶讀取, 那麼可以使用InputStreamReader(位元組流,編碼表)
* FileWriter是使用預設碼錶寫出檔案, 如果需要使用指定碼錶寫出, 那麼可以使用OutputStreamWriter(位元組流,編碼表)
public class Demo7_TransIO {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//demo1();
//demo2();
BufferedReader br = //更高效的讀
new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8"));
BufferedWriter bw = //更高效的寫
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"));
int c;
while((c = br.read()) != -1) {
bw.write(c);
}
br.close();
bw.close();
}
public static void demo2() throws UnsupportedEncodingException,
FileNotFoundException, IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "uTf-8"); //指定碼錶讀字元
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"); //指定碼錶寫字元
int c;
while((c = isr.read()) != -1) {
osw.write(c);
}
isr.close();
osw.close();
}
public static void demo1() throws FileNotFoundException, IOException {
//用預設編碼表讀寫,出現亂碼
FileReader fr = new FileReader("utf-8.txt");
FileWriter fw = new FileWriter("gbk.txt");
int c;
while((c = fr.read()) != -1) {
fw.write(c);
}
fr.close();
fw.close();
}
}
13. 轉換流圖解* 畫圖分析轉換流
14. 獲取文字上字元出現的次數
* 獲取一個文字上每個字元出現的次數,將結果寫在times.txt上
public class Test3 {
/**
* 獲取一個文字上每個字元出現的次數,將結果寫在times.txt上
*
* 分析:
* 1,建立帶緩衝的輸入流物件
* 2,建立雙列集合物件TreeMap
* 3,將讀到的字元儲存在雙列集合中,儲存的時候要做判斷,如果不包含這個鍵,就將鍵和1儲存,如果包含這個鍵,就將該鍵和值加1儲存
* 4,關閉輸入流
* 5,建立輸出流物件
* 6,遍歷集合將集合中的內容寫到times.txt中
* 7,關閉輸出流
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//1,建立帶緩衝的輸入流物件
BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
//2,建立雙列集合物件TreeMap
TreeMap<Character, Integer> tm = new TreeMap<>();
//3,將讀到的字元儲存在雙列集合中,儲存的時候要做判斷,如果不包含這個鍵,就將鍵和1儲存,如果包含這個鍵,就將該鍵和值加1儲存
int ch;
while((ch = br.read()) != -1) {
char c = (char)ch; //強制型別轉換
/*if(!tm.containsKey(c)) {
tm.put(c, 1);
}else {
tm.put(c, tm.get(c) + 1);
}*/
tm.put(c, !tm.containsKey(c) ? 1 : tm.get(c) + 1);
}
//4,關閉輸入流
br.close();
//5,建立輸出流物件
BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt"));
//6,遍歷集合將集合中的內容寫到times.txt中
for(Character key : tm.keySet()) {
switch (key) {
case '\t':
bw.write("\\t" + "=" + tm.get(key));
break;
case '\n':
bw.write("\\n" + "=" + tm.get(key));
break;
case '\r':
bw.write("\\r" + "=" + tm.get(key));
break;
default:
bw.write(key + "=" + tm.get(key)); //寫出鍵和值
break;
}
bw.newLine();
}
//7,關閉輸出流
bw.close();
}
}
15. 試用版軟體
* 當我們下載一個試用版軟體,沒有購買正版的時候,每執行一次就會提醒我們還有多少次使用機會用學過的IO流知識,模擬試用版軟體,試用10次機會,執行一次就提示一次您還有幾次機會,如果次數到了提示請購買正版
public class Test4 {
/**
* 當我們下載一個試用版軟體,沒有購買正版的時候,每執行一次就會提醒我們還有多少次使用機會用學過的IO流知識,模擬試用版軟體,
* 試用10次機會,執行一次就提示一次您還有幾次機會,如果次數到了提示請購買正版
* @throws IOException
* 分析:
* 1,建立帶緩衝的輸入流物件,因為要使用readLine方法,可以保證資料的原樣性
* 2,將讀到的字串轉換為int數
* 3,對int數進行判斷,如果大於0,就將其--寫回去,如果不大於0,就提示請購買正版
* 4,在if判斷中要將--的結果列印,並將結果通過輸出流寫到檔案上
*/
public static void main(String[] args) throws IOException {
//1,建立帶緩衝的輸入流物件,因為要使用readLine方法,可以保證資料的原樣性
BufferedReader br = new BufferedReader(new FileReader("config.txt"));
//2,將讀到的字串轉換為int數
String line = br.readLine();
int times = Integer.parseInt(line); //將數字字串轉換為數字
//3,對int數進行判斷,如果大於0,就將其--寫回去,如果不大於0,就提示請購買正版
if(times > 0) {
//4,在if判斷中要將--的結果列印,並將結果通過輸出流寫到檔案上
System.out.println("您還有" + times-- + "次機會");
FileWriter fw = new FileWriter("config.txt");
fw.write(times + "");
fw.close();
}else {
System.out.println("您的試用次數已到,請購買正版");
}
//關閉流
br.close();
}
}