day16【字節流、字符流、Properties】
反饋和複習
1.File類(瞭解)
2.遞歸(瞭解)
3.字節流(重點)
FileOutputStream: 寫文件
構造方法:
public FileOutputStream(String path/File file);
/**
* 構造方法幹了三件事!!
a.創建對象
b.判斷文件是否存在,如果存在清空文件內容,如果不存在創建文件
c.流對象和文件綁定
*/
成員方法:
public void close();釋放資源
public void flush(); 刷新緩衝區(對於字節流來說,我們不會用它)
public void write(int b);
public void write(byte[] bs);
public void write(byte[] bs,int startIndex,int len);
FileInputStream: 讀文件
構造方法:
public FileInputStream(String path/File file);
/**
* 構造方法幹了三件事!!
a.創建對象
b.判斷文件是否存在,如果存在不會清空,如果不存在直接報錯!!
c.流對象和文件綁定
*/
成員方法:
public void close();釋放資源
public int read();
public int read(byte[] bs);
今日內容
1.字符流(重點)
2.IO流異常處理(標準處理代碼)(重點)
3.Properties屬性集(重點)
4.ResourceBundle工具類(專門用於屬性集保存之後的文件)(重點)
第一章 字符流
1.爲什麼要用字符流
首先字節流也是可以讀取文本文件的!!!但是可能會出現一種狀況,讀取中文時只讀取其中一般,因爲中文不只由一個字節組成.
爲了解決這個問題,引入了字符流,以字符作爲單位來操作!!
2.字符輸入流
頂層父類: Reader(抽象類)
共性方法:
public void close(); 釋放資源
public int read(); 一次讀一個字符
public int read(char[] chs); 一次讀取一個字符數組,返回值表示實際讀取的字符個數
3.FileReader類的使用
文件的字符輸入流(從文件中讀取字符數據)
-
a.構造方法
public FileReader(String path); public FileReader(File file); public class TestFileReader01 { public static void main(String[] args) throws Exception { //1.創建一個FileReader對象 FileReader fr = new FileReader("1.txt"); // FileReader fr = new FileReader(new File("1.txt")); /** * 以上構造幹了三件事!! * a.創建對象fr * b.判斷文件是否存在 * 如果存在,不清空!!! * 如果不存在,報錯! * c.綁定fr和1.txt文件 */ } }
-
b.讀取一個字符
public class TestFileReader02 { public static void main(String[] args) throws Exception { //1.創建一個FileReader對象 FileReader fr = new FileReader("1.txt"); //2.一次讀一個字符 //int ch = fr.read(); //System.out.println((char) ch); //===========一次讀取一個字符的標準循環代碼=========== int ch = 0; //用來保存讀取到的字符 /** * (ch = fr.read()) != -1 * 以上代碼幹了三件事!! * a.讀取 fr.read(); * b.賦值 ch = 讀到的字符 * c.判斷 ch != -1 */ while ((ch = fr.read()) != -1) { System.out.println((char) ch); } //3.釋放資源 fr.close(); } }
-
c.讀取一個字符數組
public class TestFileReader03 { public static void main(String[] args) throws Exception { //1.創建一個FileReader對象 FileReader fr = new FileReader("1.txt"); //2.一次讀一個字符數組 //char[] chs = new char[4]; //int len = fr.read(chs); //System.out.println("實際讀取到"+len+"個字符"); //System.out.println(new String(chs,0,len)); char[] chs = new char[4]; //保存字符數據的數組 int len = 0;//保存實際讀取的個數 /** * (len = fr.read(chs)) != -1 * 以上代碼也是幹了三件事!!! * a.讀取 fr.read(chs); * b.賦值 len = 實際讀取的個數 * c.判斷 len != -1 */ while ((len = fr.read(chs)) != -1) { System.out.println(new String(chs,0,len)); } //3.釋放資源 fr.close(); } }
4.字符輸出流
頂層父類:Writer(抽象類)
共性方法:
public void close();//釋放資源
public void flush();//對於字符流來說有用!!
public void write(int ch); //寫一個字符
public void write(char[] chs); //寫一個字符數組
public void write(char[] chs,int startIndex,int len); //寫一個字符數組的一部分
public void write(String str);// 直接寫一個字符串
public void write(String str,int startIndex,int len);// 直接寫一個字符串的一部分
5.FileWriter類的使用
文件的字符輸出流(向文件中寫字符數據)
-
a.構造方法
public FileWriter(String path); public FileWriter(File file); public class TestFileWriter01 { public static void main(String[] args) throws IOException { //1.創建一個FileWriter對象 FileWriter fw = new FileWriter("2.txt"); // FileWriter fw = new FileWriter(new File("2.txt")); /** * 以上構造幹了三件事 * a.創建對象fw * b.判斷文件是否存在 * 如果存在,清空文件內容 * 如果不存在,會創建文件 * c.綁定fw和2.txt */ } }
-
b.寫出字符數據的三組方法
public void write(int ch); //寫一個字符 public void write(char[] chs); //寫一個字符數組 public void write(char[] chs,int startIndex,int len); //寫一個字符數組的一部分 public void write(String str);// 直接寫一個字符串 public void write(String str,int startIndex,int len);// 直接寫一個字符串的一部分 public class TestFileWriter02 { public static void main(String[] args) throws IOException { //1.創建一個FileWriter對象 FileWriter fw = new FileWriter("2.txt"); //2.寫數據 //a.寫一個字符 fw.write('a'); fw.write('中'); //b.寫一個字符數組 char[] chs = {'中','國','j','a','v','a','!'}; fw.write(chs); //c.寫一個字符數組的一部分 fw.write(chs,3,2); //d.直接寫一個字符串 fw.write("中國萬歲我愛你Java,你愛我嗎?"); //e.直接寫一個字符串的一部分 fw.write("中國萬歲我愛你Java,你愛我嗎?",0,4); //3.釋放資源 fw.close(); } }
-
c.關閉和刷新的區別
flush(); 只會刷新緩衝區,不關閉流,流可以繼續使用 close(); 不僅會刷新緩衝區,還會關閉流,流不能繼續使用 public class TestFileWriter03 { public static void main(String[] args) throws IOException { //1.創建一個FileWriter對象 FileWriter fw = new FileWriter("3.txt"); //2.寫數據 fw.write("php"); //3.刷新緩衝 fw.flush(); //再次寫數據,OK的 fw.write("python"); fw.flush(); //4.釋放資源 fw.close(); //再次寫數據,報錯,流已經關閉 fw.write("python"); fw.flush(); } }
-
d.續寫和換行
如何續寫: 很簡單!!! 只要使用下面這個兩個構造即可 public FileWriter(String path,boolean append);//append表示是否需要續寫 public FileWriter(File file,boolean append);//append表示是否需要續寫 public class TestFileWriter04 { public static void main(String[] args) throws IOException { //1.創建一個FileWriter對象,保證續寫 FileWriter fw = new FileWriter("3.txt", true); //2.續寫 fw.write("python"); //3.釋放資源 fw.close(); } } 如何換行: 很簡單!!! 向文件中寫一個換行符即可 windows: \r\n(windows系統必須使用\r\n) Linux: \n MacOS: \r (MacOSX以及以後的系統,也是\n) public class TestFileWriter05 { public static void main(String[] args) throws IOException { //1.創建一個FileWriter對象 FileWriter fw = new FileWriter("4.txt"); //2.寫數據 for (int i = 0; i < 10; i++) { fw.write("c++\r\n"); // fw.write("\r\n"); } //3.釋放資源 fw.close(); } }
第二章 IO流的異常處理
1.JDK7之前的標準IO處理
//IO流異常的標準處理方式(JDK1.7以前)
public static void method01() {
//1.創建FileReader
FileReader fr = null;
try {
fr = new FileReader("1.txt");
//2.讀
int ch = fr.read();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
//寫釋放資源的代碼
//3.釋放資源
try {
if (fr != null) {
fr.close();
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
2.JDK7引入的IO處理
try-with-resource(和資源一起try)
格式:
try(創建資源的代碼;創建資源的代碼;創建資源的代碼){
}catch(XxxException e){
}
//IO流異常的標準處理方式(JDK1.7)
public static void method02() {
try (FileReader fr = new FileReader("1.txt")) {
int ch = fr.read();
System.out.println((char) ch);
} catch (IOException e) {
e.printStackTrace();
}
}
第三章 Properties類
1.Propertie類的介紹
a.Properties就是一個雙列集合(Properties extends HashTable extends Dictionary implments Map)
b.Properties的鍵和值已經確定爲String了
c.通過System類的靜態方法.getProperties()可以獲取系統先關的一些鍵值對
public static void main(String[] args) {
//1.學過System類
// System.exit(0); //退出JVM
// long timeMillis = System.currentTimeMillis();//獲取當前時間的毫秒值
Properties ps = System.getProperties();//獲取系統相關的一些鍵值對
System.out.println(ps);//
}
2.構造方法
public Properties(); //創建一個空的Properties對象
public static void main(String[] args) {
//1.創建一個空的Properties對象
Properties ps = new Properties();
System.out.println(ps);
}
3.基本保存數據的方法
回憶一下Map接口中定義的方法:
增: put(鍵,值)
刪: remove(鍵)
改: put(鍵,值)
查: get(鍵)
遍歷的兩個方法:
Set<鍵的類型> keys = map.keySet();
Set<Map.Entry<K,V>> entrys = map.entrySet();
Properties也具有以上方法,但是我們一般使用其特有方法
public Object setProperty(String key, String value);添加/修改鍵值對, 和put功能是一樣的
public String getProperty(String key); 以鍵找值,和get功能是一樣
public Set<String> stringPropertyNames();獲取所有屬性名的集合,和keySet功能是一樣
public class PropertiesDemo02 {
public static void main(String[] args) {
//1.創建一個空的Properties對象
Properties ps = new Properties();
System.out.println(ps);
//2.添加屬性(鍵值對)
ps.setProperty("xiaomi","6888");
ps.setProperty("huawei","8888");
ps.setProperty("vivo","2222");
System.out.println(ps);
//3.修改
ps.setProperty("vivo","3333");
System.out.println(ps);
//4.獲取
System.out.println(ps.getProperty("huawei"));
//5.獲取所有的屬性名(鍵!)
Set<String> propertyNames = ps.stringPropertyNames();// 和 keySet
System.out.println(propertyNames);
}
}
4.與流相關的方法
Properties有兩個和流相關的方法,一個叫保存,一個加加載
public void store(OutputStream out,String 說明內容); //保存Properties對象中的數據
public void store(Writer write,String 說明內容);//保存Properties對象中的數據
public void load(InputStream in);//把Properties文件內容加到當前對象
public void load(Reader r);//把Properties文件內容加到當前對象
public class PropertiesDemo03 {
public static void main(String[] args) throws Exception {
//1.創建一個空的Properties對象
Properties ps = new Properties();
//2.添加
ps.setProperty("username","root");
ps.setProperty("password","123321");
//3.保存,規範,文件名建議使用.properties作爲後綴
ps.store(new FileOutputStream("5.properties"),"this is a test file");
//4.加載
ps.load(new FileInputStream("5.properties"));
System.out.println(ps);
}
}
注意: 一般我們不會使用Properties文件來保存中文數據
第四章 ResourceBundle工具類
1.ResourceBundle類的介紹
ResourceBundle實際上是一個抽象類,他的子類PropertyResourceBundle,可以讀取以.properties爲後綴的文件中的內容
2.ResourceBundle類對象的創建
public static ResourceBundle getBundle(String baseName); 用於綁定指定的.properties資源文件
注意:
a.xxx.properties文件必須放在類的根路徑下(src文件夾下)
b.給定參數時,我們只需要給文件名的名字,不需要寫文件的後綴
public class ResourceBundleDemo {
public static void main(String[] args) {
//1.創建一個ResourceBundle實現類的對象
ResourceBundle resourceBundle = ResourceBundle.getBundle("data");
System.out.println(resourceBundle);
}
}
3.ResourceBundle讀取配置文件操作
public String getString(String key);
public class ResourceBundleDemo {
public static void main(String[] args) {
//1.創建一個ResourceBundle實現類的對象
ResourceBundle resourceBundle = ResourceBundle.getBundle("data");
System.out.println(resourceBundle);
//2.根據鍵獲取值
String password = resourceBundle.getString("password");
String username = resourceBundle.getString("username");
//3.打印
System.out.println(username);
System.out.println(password);
}
}
同學們提出的問題
1.打印是地址值和內容的都有哪些
a.數組(除了char數組)都是打印地址
b.集合(Collection還是Map)都是打印內容
c.其他類的對象,打印出來是地址還是內容,就看是否重寫toString
2.排序的工具類
對數組進行排序: Arrays.sort(數組,new Comparator<數組的元素類型>(){});
對List集合排序: Collections.sort(List集合,new Comparator<集合中元素類型>(){})
對Set集合排序: 並不是所有的Set都能排序的,TreeSet纔可以排序
TreeSet怎麼排序: TreeSet set = new TreeSet(new 比較器對象())
寫排序算法: 冒泡排序,選擇排序,插入排序,希爾排序,快速排序,堆排序,歸併排序...
3.Stream流和IO流沒有關係
4.字節流 可以操作任意文件(一切皆字節)
字符流 只能操作文本文件(如果使用字符流操作圖片,視頻,那麼必須看到的結果是亂碼!!!)
5.線程池(保存線程的集合)
ExecutorService service = Executors.newFixedThreadPool(4);
線程池對象,底層實際上有一個集合:
LinkedList<Thread> list = new LinkedList<Thread>();
for(int i = 0;i < 4;i++){
list.add(線程對象);
}
service.submit(任務對象);
// list.removeFirst(): list.addLast(線程)