Day22_IO第四天

一、合併流(序列流)-SequenceInputStream(瞭解)java

概念
    合併流也叫序列流, 能夠把多個字節輸入流整合成一個, 從序列流中讀取數據時, 將從被整合的第一個流開始讀, 讀完一個以後繼續讀第二個, 以此類推.

一、將兩個輸入流合併
   
   
   
   
public static void demo1() throws FileNotFoundException, IOException { FileInputStream fis1 = new FileInputStream("a.txt"); //建立字節輸入流關聯a.txt FileOutputStream fos = new FileOutputStream("c.txt"); //建立字節輸出流關聯c.txt int b1; while((b1 = fis1.read()) != -1) { //不斷的在a.txt上讀取字節 fos.write(b1); //將讀到的字節寫到c.txt上 } fis1.close(); //關閉字節輸入流 FileInputStream fis2 = new FileInputStream("b.txt"); int b2; while((b2 = fis2.read()) != -1) { fos.write(b2); } fis2.close(); fos.close(); }

二、將多個輸入流合併
   
   
   
   
public static void main(String[] args) throws IOException { //demo1(); //demo2(); FileInputStream fis1 = new FileInputStream("a.txt"); FileInputStream fis2 = new FileInputStream("b.txt"); FileInputStream fis3 = new FileInputStream("c.txt"); Vector<FileInputStream> v = new Vector<>(); //建立集合對象 v.add(fis1); //將流對象存儲進來 v.add(fis2); v.add(fis3); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); //將枚舉中的輸入流整合成一個 FileOutputStream fos = new FileOutputStream("d.txt"); int b; while((b = sis.read()) != -1) { fos.write(b); } sis.close(); fos.close(); }


二、字節數組流(內存輸出流)-ByteArrayOutputStream(掌握)web

概念
    該輸出流能夠向內存中寫數據, 把內存看成一個緩衝區, 寫出以後能夠一次性獲取出全部數據
.使用方式
建立對象: new ByteArrayOutputStream()
寫出數據: write(int), write(byte[])
獲取數據: toByteArray()

案例:定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(byte數組大小限制爲5)


三、隨機流-RandomAccessFile(瞭解)面試

概述
RandomAccessFile概述
RandomAccessFile類不屬於流,是Object類的子類。但它融合了InputStream和OutputStream的功能。
支持對文件指定位置的讀取和寫入。換句話說寫入和讀取以前必須先指定位置

方法
    read(),write()配合seek(位置)
      一、先調用seek(10)在調用write,在10這個位置寫入
      二、先調用seek(10)再調用read,讀取10這個位置的數據

四、序列化流(對象操做流)-ObjectInputStream\ObjectOutputStream(掌握)數組

序列化概念
    把內存中的數據寫入到硬盤
反序列化概念
    把硬盤中的數據讀取到內存中
注意事項
    被序列化的類要實現 Serializable接口

解決黃色警告線問題
    給類增長 serialVersionUID屬性
方法
    ObjectOutputStream的writeObject() 方法:將對象寫入到文件
    ObjectInputStream的readObject()方法:將文件中的對象讀取出來

演示:
    
    
    
    








* 將對象存儲在集合中寫出 Person p1 = new Person("張三", 23); Person p2 = new Person("李四", 24); Person p3 = new Person("馬哥", 18); Person p4 = new Person("輝哥", 20); ArrayList<Person> list = new ArrayList<>(); list.add(p1); list.add(p2); list.add(p3); list.add(p4); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("f.txt")); oos.writeObject(list); //寫出集合對象 oos.close();* 讀取到的是一個集合對象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("f.txt")); ArrayList<Person> list = (ArrayList<Person>)ois.readObject(); //泛型在運行期會被擦除,索引運行期至關於沒有泛型 //想去掉黃色能夠加註解 @SuppressWarnings("unchecked") for (Person person : list) { System.out.println(person); } ois.close();


五、數據輸入輸出流DataInputStream\ DataOutputStream(瞭解)服務器

1.什麼是數據輸入輸出流
* DataInputStream, DataOutputStream能夠按照基本數據類型大小讀寫數據
* 例如按Long大小寫出一個數字, 寫出時該數據佔8字節. 讀取的時候也能夠按照Long類型讀取, 一次讀取8個字節.
2.使用方式
* DataOutputStream(OutputStream), writeInt(), writeLong() 

DataOutputStream dos = new DataOutputStream(new FileOutputStream("b.txt"));
dos.writeInt(997);
dos.writeInt(998);
dos.writeInt(999);
dos.close();
* DataInputStream(InputStream), readInt(), readLong()

DataInputStream dis = new DataInputStream(new FileInputStream("b.txt"));
int x = dis.readInt();
int y = dis.readInt();
int z = dis.readInt();
System.out.println(x);
System.out.println(y);
System.out.println(z);
dis.close();


六、打印流(掌握PrintWriter)網絡

概念
     該流能夠很方便的將對象的toString()結果輸出, 而且自動加上換行, 並且可使用自動刷出的模式

特色(掌握)
      A、能夠寫入任意類型數據
      B、能夠自動刷新。必須先啓動,而且是使用println.方法纔有效,而咱們的print方法僅僅是能夠寫入任意類型的數據
     C、能夠直接對文件進行寫入
     D、底層調用的是轉換流

注意事項(掌握)
     打印流只能輸出數據,不能讀取數據換句話說就是隻能操做數據目的能操做數據源

PrintWriter 和 PrintStream的區別
     一、PrintWriter構造方法能夠傳入字符流或者字節流,而PrintStream只能傳入字節流
     二、PrintWriter想要實現自動刷新構造方法必須手動指定,而PrintStream則不須要手動指定


使用
     咱們使用打印流就是爲了使用自動刷新功能,因此如下只針對如何實現自動刷新進行案例演示
     
A、PrintWriter的使用方式(掌握)
          一、經過構造方法建立對象而且啓用自動刷新功能
                    PrintWriter(OutputStrem out, boolean autoFlush);
                    PrintWriter(Writer out, boolean autoFlush);
          二、調用println\printf\format方法,只有調用這三個個方法纔會自動調用flush方法
                
     
     
     
     
PrintWriter printWriter = newPrintWriter(new FileWriter("d.txt"),true);printWriter.printf("1");//僅僅寫入數據而且刷新printWriter.println("2");//寫入數據而且增長換行符,刷新printWriter.format("你好 %s", "張三");
B、PrintStream的使用方式
           一、經過構造方法建立對象而且啓用自動刷新功能
                              PrintStream(OutputStrem out, boolean autoFlush);
          二、調用println\printf\format方法
          
    
    
    
    
PrintStream ps = newPrintStream(new FileOutputStream("a.txt"),true);//,true無關緊要ps.printf("你好");

               

七、Properties(掌握)app

一、概述
      Properties是一個鍵值對的 集合類,不是IO類 鍵和值都是字符串。能夠從流中加載數據或者把數據保存到流中,是惟一一個能夠和IO流集合使用的集合類
添加修改
public Object put(Object key, Object value)
添加修改
public Object setProperty(String key,String value)
調用的就是   put 方法
獲取功能
public String get(String key)
獲取
Public String getProperty(String key)
底層調用的是   get
Public String getProperty(String, String defaultValue)
底層調用   get, 若是找不到,返回   defaultValue
public Set<String> stringPropertyNames()
獲取鍵集合
轉換功能
public void list(PrintWriter out)
將當前的集合裏面的鍵值保存到指定的文本中
 
public void list(PrintStream out)
public void load(InputStream inputStream)
從輸入流中讀取屬性和列表
public void load(Reader reader)
public void store(OutputStream out, String comment)
把集合中的數據保存到文本中
public void store(Writer writer, String comments)
public Set keySet()
獲取全部鍵的集合


注意:Properties類在之後Android中會有新的Properties替代,在EE中咱們會從新封裝一個Properties工具類,由於Properties的缺點很明顯,不能直接操做File對象
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo {
    /**
     * 經過Properties修改config.inf中的PhoneIndex,值修改爲123
     * @param args
     */
    public static void main(String[] args) throws Exception {
        /*
         * 一、加載config.inf
         * 二、在內存修改config.inf中的phoneIndex
         * 三、將修改後的集合從新寫入到配置文件
         */
        Properties p  = new Properties();
        p.load(new FileInputStream("config.inf"));
        
        
        p.put("PhoneIndex","123");
        p.store(new FileOutputStream("config.inf"), "PhoneIndex被修改過!!!");
        
    }
}
  

八、System類(掌握)dom

一、系統類,提供了靜態的變量和方法供咱們使用
二、成員方法

public static void exit(int value)jvm

退出jvm,非0表示異常退出ide

public static long currentTimeMillis()

返回當前系統時間的毫秒值

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

從指定源數的指定位置開始複製,賦值到目標數組的指定位置

public static Properties getProperties();

獲取當前系統的屬性

public static String getProperty(String key)

獲取指定鍵描述的系統屬性

public static String getProperty(String key, String defaultValue)

獲取指定鍵描述的系統屬性,沒有找到該鍵的話返回defaultValue


遍歷Properties 
     
     
     
     
/** * 遍歷系統描述Properties */ public static voidmain(String[] args) throws Exception{ Properties properties = System.getProperties(); Set<Object> keySet = properties.keySet(); for(Object key:keySet){ System.out.println(key +"*****"+properties.get(key)); } }

獲取當前系統中的換行符
     
     
     
     
/** * 獲取當前系統中的換行符 */ public static voidmain(String[] args) throws Exception{ String line = System.getProperty("line.separator"); System.out.println(line+"你好"); }


九、IO體系(掌握)




十、案例(掌握)

一、定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(byte數組大小限制爲5)
二、兩種方式實現鍵盤錄入
三、改變標準輸入輸出流拷貝圖片
四、我有一個學生類,這個類包含如下成員變量:姓名,語文成績,數學成績,英語成績

         請從鍵盤錄入5個學生信息,而後按照本身定義的格式存儲到文本文件中。

         要求被存儲的學生按照分數從高到低排序


五、定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(兩種方式,不用字節數組流作)

十一、案例代碼(掌握)

一、定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(byte數組大小限制爲5)
      
      
      
      
package com.heima.test;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class Test1 { /** * @param args * 定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(byte數組大小限制爲5) * * 分析: * 1,reda(byte[] b)是字節輸入流的方法,建立FileInputStream,關聯a.txt * 2,建立內存輸出流,將讀到的數據寫到內存輸出流中 * 3,建立字節數組,長度爲5 * 4,將內存輸出流的數據所有轉換爲字符串打印 * 5,關閉輸入流 * @throws IOException */ public static void main(String[] args) throws IOException { //1,reda(byte[] b)是字節輸入流的方法,建立FileInputStream,關聯a.txt FileInputStream fis = new FileInputStream("a.txt"); //2,建立內存輸出流,將讀到的數據寫到內存輸出流中 ByteArrayOutputStream baos = new ByteArrayOutputStream(); //3,建立字節數組,長度爲5 byte[] arr = new byte[5]; int len; while((len = fis.read(arr)) != -1) { baos.write(arr, 0, len); //System.out.println(new String(arr,0,len)); } //4,將內存輸出流的數據所有轉換爲字符串打印 System.out.println(baos); //即便沒有調用,底層也會默認幫咱們調用toString()方法 //5,關閉輸入流 fis.close(); }}

二、兩種方式實現鍵盤錄入
       
       
       
       
package com.heima.otherio;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Scanner;public class Demo07_SystemIn { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //方式1 /*BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //InputStreamReader轉換流 String line = br.readLine(); System.out.println(line); br.close();*/ //方式2 Scanner sc = new Scanner(System.in); String line = sc.nextLine(); System.out.println(line); sc.close(); }}

三、改變標準輸入輸出流拷貝圖片
       
       
       
       
package com.heima.test;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;public class Test2 { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { System.setIn(new FileInputStream("雙元.jpg")); //改變標準輸入流 System.setOut(new PrintStream("copy.jpg")); //改變標準輸出流 InputStream is = System.in; PrintStream ps = System.out; byte[] arr = new byte[1024]; int len; while((len = is.read(arr)) != -1) { ps.write(arr, 0, len); } is.close(); ps.close(); }}
四、 我有一個學生類,這個類包含如下成員變量: 姓名,語文成績,數學成績,英語成績

         請從鍵盤錄入5個學生信息,而後按照本身定義的格式存儲到文本文件中。

         要求被存儲的學生按照分數從高到低排序


      
      
      
      
package cn.itcast;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.util.Comparator;import java.util.Scanner;import java.util.TreeSet;/* * 我有一個學生類,這個類包含一下成員變量:姓名,語文成績,數學成績,英語成績。 * 請從鍵盤錄入5個學生信息,而後按照本身定義的格式存儲到文本文件中。 * 要求被存儲的學生按照分數從高到低排序。 * * 分析: * A:寫一個學生類,有4個成員變量。 * B:用Scanner實現鍵盤錄入。 * C:把這多個學生進行存儲。用集合。 * 那麼,用哪一個集合呢? * 因爲最終須要排序,因此,咱們選擇TreeSet集合。 * D:遍歷集合,獲取到集合中的每個數據,用輸出流寫到文本文件。 * name chinese math english */public class StudentTest { public static void main(String[] args) throws IOException { // 寫一個學生類,有4個成員變量。 System.out.println("學生信息錄入開始"); // 定義TreeSet集合 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // 主要條件 int num = s2.getSum() - s1.getSum(); // 分析次要條件 // 當總分相同,還得繼續比較每一門的分數是否相同 int num2 = (num == 0) ? s1.getChinese() - s2.getChinese() : num; int num3 = (num2 == 0) ? s1.getMath() - s2.getMath() : num2; // 當語文,數學,英語成績都相同的,咱們還得繼續判斷姓名是否相同。 int num4 = (num3 == 0) ? s1.getName().compareTo(s2.getName()) : num3; return num4; } }); for (int x = 0; x < 5; x++) { // 用Scanner實現鍵盤錄入。 Scanner sc = new Scanner(System.in); // 鍵盤錄入數據 System.out.println("請輸入第" + (x + 1) + "個學生的姓名:"); String name = sc.nextLine(); System.out.println("請輸入第" + (x + 1) + "個學生的語文成績:"); int chinese = sc.nextInt(); System.out.println("請輸入第" + (x + 1) + "個學生的數學成績:"); int math = sc.nextInt(); System.out.println("請輸入第" + (x + 1) + "個學生的英語成績:"); int english = sc.nextInt(); // 把數據封裝到學生對象中 Student s = new Student(); s.setName(name); s.setChinese(chinese); s.setMath(math); s.setEnglish(english); ts.add(s); } // 遍歷集合,獲取到集合中的每個數據,用輸出流寫到文本文件。 BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt")); bw.write("姓名\t語文\t數學\t英語"); bw.newLine(); bw.flush(); for (Student s : ts) { StringBuilder sb = new StringBuilder(); sb.append(s.getName()).append("\t").append(s.getChinese()) .append("\t").append(s.getMath()).append("\t") .append(s.getEnglish()); bw.write(sb.toString()); bw.newLine(); bw.flush(); } bw.close(); System.out.println("學生信息錄入成功"); }}

       
       
       
       
package cn.itcast;public class Student { private String name; private int chinese; private int math; private int english; public Student() { } public Student(String name, int chinese, int math, int english) { super(); this.name = name; this.chinese = chinese; this.math = math; this.english = english; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChinese() { return chinese; } public void setChinese(int chinese) { this.chinese = chinese; } public int getMath() { return math; } public void setMath(int math) { this.math = math; } public int getEnglish() { return english; } public void setEnglish(int english) { this.english = english; } public int getSum() { return this.chinese + this.math + this.english; }}


五、定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(兩種方式,不用字節數組流作)
       
       
       
       
FileInputStream fileInputStream = new FileInputStream("LineNumberReader.java"); byte[] data = new byte[fileInputStream.available()]; int len = fileInputStream.read(data); System.out.println(new String(data,0,len));

十二、關於Serializable的Serial Version ID的討論(瞭解)

     咱們編寫一個實現了 Serializable 接口(序列化標誌接口)的類, Eclipse 立刻就會給一個黃色警告:須要增長一個 Serial Version ID 爲何要增長它是怎麼計算出來的?有什麼用?


    一、爲何要增長?
               類實現 Serializable 接口的目的是爲了將內存中的對象保存到本地磁盤或者經過網絡傳輸(也就是可持久化)
無標題.png
       
       
       
       
package io;/** * 騰訊新聞手機客戶端 * @author haoyongliang * */public class Consumer { public static void main(String[] args) { Person person = (Person)SerializationUtils.readObject(); System.out.println(person.getName()); }}


       
       
       
       
package io;/** * 騰訊新聞服務器 * @author haoyongliang * */public class Producer { public static void main(String[] args) { Person person = new Person(); person.setName("混世魔王"); SerializationUtils.writeObject(person); }}

       
       
       
       
package io;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;/** * 序列化工具類 * @author haoyongliang * */public class SerializationUtils { /** 序列化後的對象存儲路徑 */ private static final String FILE_NAME = "C://obj.bin"; public static void writeObject(Serializable s) { try ( ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME)); ){ oos.writeObject(s);//將對象寫入到C://obj.bin } catch (Exception e) { e.printStackTrace(); } } public static Object readObject(){ Object obj = null; try( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME)) ){ obj = ois.readObject(); }catch(Exception e){ e.printStackTrace(); } return obj; }}

1三、今天必須掌握的內容,面試題,筆試題。(掌握這個就能夠放心學習後面的知識了)

一、說說合並流是幹什麼的
二、說說字節數組流是幹什麼的,底層是什麼
三、說說隨即流能夠幹什麼
四、說說序列化流,而且經過序列化流將學生對象寫入文件,而且將文件中的數據讀取成學生對象
五、打印流有哪些,打印流能夠讀取數據嗎?打印流的特色是什麼,要想啓用刷新功能,必須調用哪一個方法
六、代碼題:定義一個文件輸入流,調用read(byte[] b)方法,將a.txt文件中的內容打印出來(byte數組大小限制爲5)
七、代碼題:兩種方式實現鍵盤錄入
八、代碼題:我有一個學生類,這個類包含如下成員變量:姓名,語文成績,數學成績,英語成績

         請從鍵盤錄入5個學生信息,而後按照本身定義的格式存儲到文本文件中。

         要求被存儲的學生按照分數從高到低排序

九、Properties的load store方法掌握






相關文章
相關標籤/搜索