Java IO流 、 Properties 、 枚举
生活随笔
收集整理的這篇文章主要介紹了
Java IO流 、 Properties 、 枚举
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、概述
- IO流流動的是數(shù)據(jù) --- 用于傳輸數(shù)據(jù)的API。
- InputStream\OutputStream ? --- ? 輸入輸出流
- 根據(jù)流的傳輸方向分類 :?
- 當數(shù)據(jù)從外部流入程序時 ?: 輸入流
- 當數(shù)據(jù)從程序流向外部時 : 輸出流
- 根據(jù)流的傳輸形式分類:?
- 字節(jié)流
- 字符流
- 不同形式交匯,得到四種基本操作流的類 ?, 四個基本流都是抽象類
? ? ? ? 輸入流 ? ? ? 輸出流 ? ? 字符流 ? ? ? ? ? Reader ? ? ? Writer ? ? 字節(jié)流 ? ? ? InputStream ? ? ? ? ? ? OutputStream ? ??
- 數(shù)據(jù)的來源: 硬盤、網(wǎng)絡、內(nèi)存、輸入設(shè)備
- 字符輸入流示例:public class FileWriterDemo1 {public static void main(String[] args) throws Exception {// 無論這個文件是否存在,都會創(chuàng)建一個新的文件 ,不存在則創(chuàng)建,存在則覆蓋FileWriter writer = new FileWriter("E:\\a.txt");// 寫出數(shù)據(jù)// java在底層對字符流設(shè)計了一個緩沖區(qū),數(shù)據(jù)并不是直接寫到目的地而是先寫到了緩沖區(qū)中// 等緩沖區(qū)滿了之后才會將緩沖區(qū)中的數(shù)據(jù)一次性的放到目的地中。// 由于緩沖區(qū)沒有滿而代碼已經(jīng)結(jié)束,所以數(shù)據(jù)就死在了緩沖區(qū)中writer.write("def");// 沖刷緩沖區(qū)// writer.flush();// 關(guān)閉流對象// 流在關(guān)閉之前會自動的沖刷緩沖區(qū),以防有數(shù)據(jù)死在緩沖區(qū)中writer.close();// 流在關(guān)閉之后依然存在,依然在占用內(nèi)存writer = null;System.out.println(writer);}}
- 字符輸出流示例:public class FileReaderDemo2 {public static void main(String[] args) throws Exception {FileReader reader = new FileReader("E:\\a.txt");// 創(chuàng)建一個字符數(shù)組作為緩沖區(qū)char[] cs = new char[5];// 定義一個變量來記錄每次讀取到字符個數(shù)int len = -1;// 讀取數(shù)據(jù),將數(shù)據(jù)讀取到字符數(shù)組中while ((len = reader.read(cs)) != -1) {System.out.println(new String(cs, 0, len));}// 關(guān)流reader.close();}}
- 字節(jié)輸入流示例:public class FileInputStreamDemo {public static void main(String[] args) throws Exception {FileInputStream fin = new FileInputStream("E:\\a.txt");// 創(chuàng)建一個字節(jié)數(shù)組作為緩沖區(qū)byte[] bs = new byte[3];// 定義一個變量來記錄每次讀取的字節(jié)個數(shù)int len = -1;while ((len = fin.read(bs)) != -1) {System.out.println(new String(bs, 0, len));}fin.close();}}
- 字節(jié)輸出流示例:public class FileOutputStreamDemo {public static void main(String[] args) throws Exception {FileOutputStream writer = new FileOutputStream("E:\\c.txt");// 沒有緩沖區(qū)writer.write("abc".getBytes());// 關(guān)流writer.close();}}
二、流的異常處理
- 第一步:流對象外置定義 ?內(nèi)置初始化
- 第二步:防止流對象關(guān)閉時出現(xiàn)空指針異常 ,關(guān)閉前 對流對象判空
- 第三步:如果關(guān)流失敗,則強制釋放 ?;如果關(guān)流成功,則釋放流對象 ,釋放內(nèi)存
- 第四步:防止關(guān)流失敗 ,在關(guān)流之前手動沖刷緩沖區(qū)
- 示例:package cn.tedu.io.file;import java.io.FileWriter;
import java.io.IOException;public class FileWriterDemo2 { public static void main(String[] args) { // 流對象要外置定義,在外置定義的時候需要把這個流對象置為null
FileWriter writer = null;
try {
// 內(nèi)置初始化
writer = new FileWriter("E:\\b.txt");
writer.write("abcdefg");
// 為了防止關(guān)流失敗導致一部分數(shù)據(jù)的丟失,因此需要提前進行flush來保證數(shù)據(jù)的完整性
writer.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 需要判斷流對象是否初始化成功
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 如果關(guān)流失敗則強制回收流對象以釋放文件
// 如果關(guān)流成功則用于釋放這個流對象占用的內(nèi)存
writer = null;
}
}
}
}}
- 練習: 剪切文件public class CutFileDemo {public static void main(String[] args) throws Exception {// 創(chuàng)建一個file對象指向源文件File oldFile = new File("E:\\a.txt");// 創(chuàng)建一個輸入流指向源文件FileReader reader = new FileReader(oldFile);// 創(chuàng)建一個輸出流來指向新文件FileWriter writer = new FileWriter("D:\\a.txt");// 創(chuàng)建一個字符數(shù)組作為緩沖區(qū)char[] cs = new char[10];// 定義一個變量記錄每次讀取到字符個數(shù)int len = -1;// 讀取數(shù)據(jù)while ((len = reader.read(cs)) != -1) {// 將讀取到數(shù)據(jù)寫出writer.write(cs, 0, len);}// 關(guān)流reader.close();writer.close();// 刪除源文件oldFile.delete();}}
三、緩沖流
- BufferedReader :從字符輸入流中讀取數(shù)據(jù) , 提供一個緩沖區(qū) , 允許按行讀取
- BufferWriter : newLine() 產(chǎn)生新的一行。
- 字符輸入緩沖流示例:public class BufferedReaderDemo {public static void main(String[] args) throws Exception {// 實際上讀取數(shù)據(jù)的流是FileReader, BufferedReader的作用是為這個流提供了一個緩沖區(qū)BufferedReader reader = new BufferedReader(new FileReader("E:\\a.txt"));// 按行讀取數(shù)據(jù)String line = null;while((line = reader.readLine()) != null){System.out.println(line);}// 關(guān)流---從里向外依次關(guān)閉// Stream Already closed.reader.close();}}
四、字節(jié)流
- 可以用字節(jié)流來讀取任意文件 ?,如: 視頻 、音頻
五、轉(zhuǎn)換流
- 將字節(jié)轉(zhuǎn)換為字符示例:?public class InputStreamReaderDemo {public static void main(String[] args) throws Exception {// 實際上讀取數(shù)據(jù)的FileInputStream,轉(zhuǎn)換流將字節(jié)轉(zhuǎn)化為字符InputStreamReader ir = new InputStreamReader(new FileInputStream("E:\\d.txt"), "utf-8");// 數(shù)據(jù)是以字符形式來返回的char[] cs = new char[4];int len = -1;while ((len = ir.read(cs)) != -1) {System.out.println(new String(cs, 0, len));}ir.close();}}
- 將字符轉(zhuǎn)換為字節(jié)示例:public class OutputStreamWriterDemo {public static void main(String[] args) throws Exception {// 在底層實際上傳輸數(shù)據(jù)的是FileOutputStream,轉(zhuǎn)換流提供的操作是將字符轉(zhuǎn)化為字節(jié)// 當沒有指定轉(zhuǎn)換編碼的時候,默認使用的是系統(tǒng)平臺碼OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream("E:\\d.txt"), "utf-8");// 寫出數(shù)據(jù)ow.write("轉(zhuǎn)換");// 關(guān)流ow.close();}}
- 練習: 改變文件的編碼public class ChangeEncodeExer {public static void main(String[] args) throws Exception {// 創(chuàng)建一個file對象指向源文件File file = new File("F:\\java基礎(chǔ)增強.txt");// 創(chuàng)建一個file對象指向臨時文件File temp = new File("F:\\temp.txt");// 創(chuàng)建一個輸入流來讀取源文件BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));// 創(chuàng)建一個輸出流將讀取的內(nèi)容寫到臨時文件中// BufferedWriter bw = new BufferedWriter(new FileWriter(temp));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(temp)));// 定義一個變量來記錄讀取的每行數(shù)據(jù)String msg = null;// 讀取數(shù)據(jù)while ((msg = br.readLine()) != null) {// 將讀取到的數(shù)據(jù)寫出bw.write(msg);// 換行bw.newLine();}// 關(guān)流br.close();bw.close();// 刪除源文件file.delete();// 重命名新文件temp.renameTo(file);}}
六、系統(tǒng)流\標準流
- 系統(tǒng)流示例:public class SystemDemo {public static void main(String[] args) throws Exception {// 系統(tǒng)流都是字節(jié)流int i = System.in.read();// 在使用的時候沒有任何差別,只是在輸出結(jié)果上有顏色的差別// 如果是正常的結(jié)果使用out來輸出打印,如果是錯誤的結(jié)果會使用err來輸出打印System.out.println(i);System.err.println(i);System.out.println(new char[]{'a','d'});System.out.println(new int[]{'a','d'});}}
- 練習: 從控制臺讀取內(nèi)容后輸出public class GetLineExer {public static void main(String[] args) throws Exception {// 從控制臺獲取---System.in// 獲取一行數(shù)據(jù)---BufferedReader// System.in是一個字節(jié),BufferedReader需要一個字符流---字節(jié)轉(zhuǎn)化成字符---InputStreamReaderBufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println(br.readLine());br.close();// br = new BufferedReader(new InputStreamReader(System.in));// System.out.println(br.readLine());// br.close();}}
七、打印流
八、 合并流
- 示例:public class SequenceInputStreamDemo {public static void main(String[] args) throws Exception {// 創(chuàng)建輸入流分別對應的文件FileInputStream in1 = new FileInputStream("E:\\a.txt");FileInputStream in2 = new FileInputStream("E:\\c.txt");FileInputStream in3 = new FileInputStream("E:\\d.txt");// 創(chuàng)建一個Vector集合Vector<InputStream> vec = new Vector<InputStream>();vec.add(in1);vec.add(in2);vec.add(in3);// 轉(zhuǎn)化為一個EnumerationEnumeration<InputStream> e = vec.elements();// 創(chuàng)建合并流對象SequenceInputStream sis = new SequenceInputStream(e);// 讀取數(shù)據(jù)byte[] bs = new byte[10];int len = -1;// 在合并的時候沒有辦法控制文件的編碼while ((len = sis.read(bs)) != -1) {System.out.println(new String(bs, 0, len));}// 關(guān)流sis.close();}}
九、序列化流\反序列化流
- 示例:public class Person implements Serializable {// 版本號---用版本號來標識一個類。// 當一個對象反序列化回來的時候,會自動的比較對象中的版本號和當前類中的版本號是否一致、// 如果一致Java才認為這個對象是本類的對象,才允許反序列化// 如果沒有手動指定版本號,JVM在編譯的時候會根據(jù)當前類中的方法和屬性自動計算一個版本號// private static final long serialVersionUID = 329L;private static final long serialVersionUID = 6920415629894220824L;private String name;private int age;private char gender;private double heigh;// 被transient修飾的屬性不能被序列化private transient double weight;public double getHeigh() {return heigh;}public void setHeigh(double heigh) {this.heigh = heigh;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}// public static boolean alive;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class SerialDemo {public static void main(String[] args) throws Exception {// 準備要序列化的對象Person p = new Person();p.setName("酸菜魚");p.setAge(16);p.setWeight(190);// p.alive = true;// 創(chuàng)建一個用于序列化的流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\p.data"));// 將對象序列化出去oos.writeObject(p);// 關(guān)流oos.close();}}public class DeserialDemo {public static void main(String[] args) throws Exception {// 創(chuàng)建反序列化流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\p.data"));// 反序列化對象Person p = (Person) ois.readObject();// 關(guān)流ois.close();System.out.println(p.getName());System.out.println(p.getAge());// 如果一個屬性沒有序列化出去,那么反序列化回來的時候會給這個屬性一個默認值System.out.println(p.getWeight());}}
- 序列化加密示例:public class 加密例子 {Key key;public void serial(Person p) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,IllegalBlockSizeException, IOException {// 需要找制作鑰匙的對象// 在此的規(guī)則指的加密算法---對稱加密,非對稱加密KeyGenerator generator = KeyGenerator.getInstance("DESede");// 產(chǎn)生鑰匙key = generator.generateKey();// 產(chǎn)生鎖Cipher cipher = Cipher.getInstance("DESede");// 將鎖和鑰匙配對// 第一個參數(shù)表示鑰匙和鎖的配對模式cipher.init(Cipher.ENCRYPT_MODE, key);// 找盒子SealedObject so = new SealedObject(p, cipher);// 將盒子序列化出去ObjectOutputStream ois = new ObjectOutputStream(new FileOutputStream("p.data"));ois.writeObject(so);ois.close();}public Person deSerial() throws FileNotFoundException, IOException, ClassNotFoundException, InvalidKeyException, NoSuchAlgorithmException{// 創(chuàng)建反序列化流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("p.data"));// 反序列化盒子SealedObject so = (SealedObject) ois.readObject();// 關(guān)流ois.close();// 將對象從盒子中取出return (Person) so.getObject(key);}public static void main(String[] args) throws Exception {加密例子 demo = new 加密例子();Person p = new Person();p.setName("張三瘋");p.setAge(500);p.setGender('男');demo.serial(p);}}
十、 Properties
- 示例:public class PropertiesDemo1 {public static void main(String[] args) throws Exception {// 創(chuàng)建properties對象Properties prop = new Properties();// 添加鍵值對prop.setProperty("key", "value");prop.setProperty("second", "value");// 持久化這個映射---必須存儲到properties文件中// 第二個參數(shù)表示給properties文件添加一個注釋---用于解釋當前properties文件的作用prop.store(new FileOutputStream("c.properties"), "this is a demo .");}}
- public class PropertiesDemo2 {public static void main(String[] args) throws Exception {Properties prop = new Properties();// 反序列化prop.load(new FileInputStream("c.properties"));System.out.println(prop.getProperty("key"));System.out.println(prop.getProperty("second","ok"));// 如果鍵不存在,則返回一個null// 如果鍵不存在,則返回指定的值---第二個參數(shù)System.out.println(prop.getProperty("鍵", "non"));}}
十一、 枚舉
- 示例1:public class EnumDemo {@SuppressWarnings("unused")public static void main(String[] args) {Season s = Season.Autumn;}}class Season {// 不允許在類外隨意創(chuàng)建對象private Season() {}static final Season Spring = new Season();static final Season Summer = new Season();static final Season Autumn = new Season();static final Season Winter = new Season();}
- 示例2:public class EnumDemo2 {public static void main(String[] args) {Level l = Level.B;// l.print();switch (l) {case A:System.out.println("ok");break;case B:System.out.println("B~~~");break;default:break;}}}enum Level {// 默認構(gòu)造函數(shù)是私有的而且只能是私有的// 每個枚舉常量之間用 , 隔開,最后一個枚舉常量之后最好加上 ; 表示結(jié)束// public static final Level A = new Level();// 枚舉常量必須定義在枚舉類的首行A(90) {@Overridepublic void print() {System.out.println("優(yōu)秀");}},B(80) {@Overridepublic void print() {System.out.println("良好");}},C(70) {@Overridepublic void print() {System.out.println("中等");}},D(60) {@Overridepublic void print() {System.out.println("及格");}},E(0) {@Overridepublic void print() {System.out.println("不及格");}};private Level(double score) {this.score = score;}private Level() {}private double score;public static double average;public double getScore() {return score;}public static void set(double sum) {System.out.println(sum / average);}public void setScore(double score) {this.score = score;}public abstract void print();}
總結(jié)
以上是生活随笔為你收集整理的Java IO流 、 Properties 、 枚举的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 文件操作 File 及 Ran
- 下一篇: Java 多线程Thread