①I(mǎi)O流(字符流FileReader)
- 1.字符流是什么
- 字符流是可以直接讀寫(xiě)字符的IO流
- 字符流讀取字符, 就要先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符. 如果要寫(xiě)出字符, 需要把字符轉(zhuǎn)為字節(jié)再寫(xiě)出.
- 2.FileReader
- FileReader類的read()方法可以按照字符大小讀取
FileReader fr = new FileReader("aaa.txt"); //創(chuàng)建輸入流對(duì)象,關(guān)聯(lián)aaa.txt int ch; while((ch = fr.read()) != -1) { //將讀到的字符賦值給ch System.out.println((char)ch); //將讀到的字符強(qiáng)轉(zhuǎn)后打印 } fr.close(); //關(guān)流
②IO流(字符流FileWriter)
-
FileWriter類的write()方法可以自動(dòng)把字符轉(zhuǎn)為字節(jié)寫(xiě)出
FileWriter fw = new FileWriter("aaa.txt"); fw.write("aaa"); fw.close();
③IO流(字符流的拷貝)
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();
④IO流(什么情況下使用字符流)
- 字符流也可以拷貝文本文件, 但不推薦使用. 因?yàn)樽x取時(shí)會(huì)把字節(jié)轉(zhuǎn)為字符, 寫(xiě)出時(shí)還要把字符轉(zhuǎn)回字節(jié).
- 程序需要讀取一段文本, 或者需要寫(xiě)出一段文本的時(shí)候可以使用字符流
- 讀取的時(shí)候是按照字符的大小讀取的,不會(huì)出現(xiàn)半個(gè)中文
- 寫(xiě)出的時(shí)候可以直接將字符串寫(xiě)出,不用轉(zhuǎn)換為字節(jié)數(shù)組
⑤IO流(字符流是否可以拷貝非純文本的文件)
- 不可以拷貝非純文本的文件
- 因?yàn)樵谧x的時(shí)候會(huì)將字節(jié)轉(zhuǎn)換為字符,在轉(zhuǎn)換過(guò)程中,可能找不到對(duì)應(yīng)的字符,就會(huì)用?代替,寫(xiě)出的時(shí)候會(huì)將字符轉(zhuǎn)換成字節(jié)寫(xiě)出去
- 如果是?,直接寫(xiě)出,這樣寫(xiě)出之后的文件就亂了,看不了了
⑥IO流(自定義字符數(shù)組的拷貝)
FileReader fr = new FileReader("aaa.txt"); //創(chuàng)建字符輸入流,關(guān)聯(lián)aaa.txt FileWriter fw = new FileWriter("bbb.txt"); //創(chuàng)建字符輸出流,關(guān)聯(lián)bbb.txt int len; char[] arr = new char[1024*8]; //創(chuàng)建字符數(shù)組 while((len = fr.read(arr)) != -1) { //將數(shù)據(jù)讀到字符數(shù)組中 fw.write(arr, 0, len); //從字符數(shù)組將數(shù)據(jù)寫(xiě)到文件上 } fr.close(); //關(guān)流釋放資源 fw.close();
⑦IO流(帶緩沖的字符流)
- BufferedReader的read()方法讀取字符時(shí)會(huì)一次讀取若干字符到緩沖區(qū), 然后逐個(gè)返回給程序, 降低讀取文件的次數(shù), 提高效率
- BufferedWriter的write()方法寫(xiě)出字符時(shí)會(huì)先寫(xiě)到緩沖區(qū), 緩沖區(qū)寫(xiě)滿時(shí)才會(huì)寫(xiě)到文件, 降低寫(xiě)文件的次數(shù), 提高效率
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); //創(chuàng)建字符輸入流對(duì)象,關(guān)聯(lián)aaa.txt BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //創(chuàng)建字符輸出流對(duì)象,關(guān)聯(lián)bbb.txt int ch; while((ch = br.read()) != -1) { //read一次,會(huì)先將緩沖區(qū)讀滿,從緩沖去中一個(gè)一個(gè)的返給臨時(shí)變量ch bw.write(ch); //write一次,是將數(shù)據(jù)裝到字符數(shù)組,裝滿后再一起寫(xiě)出去 } br.close(); //關(guān)流 bw.close();
⑧IO流(readLine()和newLine()方法)
- BufferedReader的readLine()方法可以讀取一行字符(不包含換行符號(hào))
- BufferedWriter的newLine()可以輸出一個(gè)跨平臺(tái)的換行符號(hào)"\r\n"
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系統(tǒng) bw.newLine(); //跨平臺(tái)的 } br.close(); bw.close();
⑨IO流(將文本反轉(zhuǎn))
- 將一個(gè)文本文檔上的文本反轉(zhuǎn),第一行和倒數(shù)第一行交換,第二行和倒數(shù)第二行交換
⑩IO流(LineNumberReader)
- LineNumberReader是BufferedReader的子類, 具有相同的功能, 并且可以統(tǒng)計(jì)行號(hào)
- 調(diào)用getLineNumber()方法可以獲取當(dāng)前行號(hào)
- 調(diào)用setLineNumber()方法可以設(shè)置當(dāng)前行號(hào)
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt")); String line; lnr.setLineNumber(100); //設(shè)置行號(hào) while((line = lnr.readLine()) != null) { System.out.println(lnr.getLineNumber() + ":" + line);//獲取行號(hào) } lnr.close();
11、IO流(裝飾設(shè)計(jì)模式)
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 { private Student s; //獲取到被包裝的類的引用 public ItcastStudent(Student s) { //通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象的時(shí)候,傳入被包裝的對(duì)象 this.s = s; } @Override public void code() { //對(duì)其原有功能進(jìn)行升級(jí) s.code(); System.out.println("數(shù)據(jù)庫(kù)"); System.out.println("ssh"); System.out.println("安卓"); System.out.println("....."); } }
12碴倾、IO流(使用指定的碼表讀寫(xiě)字符)
- FileReader是使用默認(rèn)碼表讀取文件, 如果需要使用指定碼表讀取, 那么可以使用InputStreamReader(字節(jié)流,編碼表)
- FileWriter是使用默認(rèn)碼表寫(xiě)出文件, 如果需要使用指定碼表寫(xiě)出, 那么可以使用OutputStreamWriter(字節(jié)流,編碼表)
BufferedReader br = //高效的用指定的編碼表讀 new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8")); BufferedWriter bw = //高效的用指定的編碼表寫(xiě) new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK")); int ch; while((ch = br.read()) != -1) { bw.write(ch); } br.close(); bw.close();
13、File類(遞歸)
- 5的階乘
package com.heima.chario;
/**
* @param args
* 遞歸:方法自己調(diào)用自己
* 5!
* 5 * 4 * 3 * 2 * 1
*
* 5 * fun(4)(代表4!)
* 4 * fun(3)(代表3!)
* 3 * fun(2)(代表2!)
* 2 * fun(1)(代表1!)
* 遞歸的弊端:不能調(diào)用次數(shù)過(guò)多,容易導(dǎo)致棧內(nèi)存溢出
* 遞歸的好處:不用知道循環(huán)次數(shù)
*
* 構(gòu)造方法是否可以遞歸調(diào)用?
* 構(gòu)造方法不能使用遞歸調(diào)用
*
* 遞歸調(diào)用是否必須有返回值?
* 不一定(可以有,也可以沒(méi)有)
*/
public static void main(String[] args) {
/*int result = 1;
for(int i = 1; i <= 5; i++) {
result = result * i;
}
System.out.println(result);*/
System.out.println(fun(6000));
}
public static int fun(int num) {
if(num == 1) {
return 1;
}else {
return num * fun(num - 1);
}
}
14、File類(練習(xí))
- 需求:從鍵盤(pán)輸入接收一個(gè)文件夾路徑,打印出該文件夾下所有的.java文件名
/**
* 需求:從鍵盤(pán)輸入接收一個(gè)文件夾路徑,打印出該文件夾下所有的.java文件名
*
* 分析:
* 從鍵盤(pán)接收一個(gè)文件夾路徑
* 1,如果錄入的是不存在,給與提示
* 2,如果錄入的是文件路徑,給與提示
* 3,如果是文件夾路徑,直接返回
*
* 打印出該文件夾下所有的.java文件名
* 1,獲取到該文件夾路徑下的所有的文件和文件夾,存儲(chǔ)在File數(shù)組中
* 2,遍歷數(shù)組,對(duì)每一個(gè)文件或文件夾做判斷
* 3,如果是文件,并且后綴是.java的,就打印
* 4,如果是文件夾,就遞歸調(diào)用
*/
public static void main(String[] args) {
File dir = getDir();
printJavaFile(dir);
}
/*
* 獲取鍵盤(pán)錄入的文件夾路徑
* 1,返回值類型File
* 2,不需要有參數(shù)
*/
public static File getDir() {
Scanner sc = new Scanner(System.in); //創(chuàng)建鍵盤(pán)錄入對(duì)象
System.out.println("請(qǐng)輸入一個(gè)文件夾路徑");
while(true) {
String line = sc.nextLine(); //將鍵盤(pán)錄入的文件夾路徑存儲(chǔ)
File dir = new File(line); //封裝成File對(duì)象
if(!dir.exists()) {
System.out.println("您錄入的文件夾路徑不存在,請(qǐng)重新錄入");
}else if(dir.isFile()) {
System.out.println("您錄入的是文件路徑,請(qǐng)重新錄入文件夾路徑");
}else {
return dir;
}
}
}
/*
* 獲取文件夾路徑下的所.java文件
* 1,返回值類型 void
* 2,參數(shù)列表File dir
*/
public static void printJavaFile(File dir) {
//1,獲取到該文件夾路徑下的所有的文件和文件夾,存儲(chǔ)在File數(shù)組中
File[] subFiles = dir.listFiles();
//2,遍歷數(shù)組,對(duì)每一個(gè)文件或文件夾做判斷
for (File subFile : subFiles) {
//3,如果是文件,并且后綴是.java的,就打印
if(subFile.isFile() && subFile.getName().endsWith(".java")) {
System.out.println(subFile);
//4,如果是文件夾,就遞歸調(diào)用
}else if (subFile.isDirectory()){
printJavaFile(subFile);
}
}
}
15谍失、IO流(總結(jié))
- 1.會(huì)用BufferedReader讀取GBK碼表和UTF-8碼表的字符
- 2.會(huì)用BufferedWriter寫(xiě)出字符到GBK碼表和UTF-8碼表的文件中
- 3.會(huì)使用BufferedReader從鍵盤(pán)讀取一行