IO流(四)
阿新 • • 發佈:2017-10-15
read and 內存操作流 取數據 obj 返回值 object類 system類 args
登錄註冊IO版本案例(掌握)
要求,對著寫一遍。 cn.itcast.pojo User cn.itcast.dao UserDao cn.itcast.dao.impl UserDaoImpl(實現我不管) cn.itcast.game GuessNumber cn.itcast.test UserTest
數據操作流(操作基本類型數據的流)(理解)
1、可以操作基本類型的數據 2、流對象名稱 DataInputStream A:創建數據輸出流對象 DataOutputStream dos = new DataOutputStream(new FileOutputStream( "dos.txt")); B:寫數據 dos.writeByte(10); dos.writeShort(100); dos.writeInt(1000); dos.writeLong(10000); dos.writeFloat(12.34F); dos.writeDouble(12.56); dos.writeChar(‘a‘); dos.writeBoolean(true); C:釋放資源 dos.close(); DataOutputStream A:創建數據輸入流對象 DataInputStream dis = new DataInputStream( new FileInputStream("dos.txt")); B:讀數據 byte b = dis.readByte(); short s = dis.readShort(); int i = dis.readInt(); long l = dis.readLong(); float f = dis.readFloat(); double d = dis.readDouble(); char c = dis.readChar(); boolean bb = dis.readBoolean(); C:釋放資源 dis.close();
內存操作流(理解)
1、有些時候我們操作完畢後,未必需要產生一個文件,就可以使用內存操作流。 2、三種 A:操作字節數組 ByteArrayInputStream //將寫入的流轉化為字符數組 byte[] bys = baos.toByteArray(); //創建對象 ByteArrayInputStream bais = new ByteArrayInputStream(bys); //讀數據 int by = 0; while ((by = bais.read()) != -1) { System.out.print((char) by); } ByteArrayOutputStream // 創建對象 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 寫數據 for (int x = 0; x < 10; x++) { baos.write(("hello" + x).getBytes()); } // 釋放資源 // 通過查看源碼我們知道這裏什麽都沒做,所以根本需要close() // baos.close(); B:操作字符數組 CharArrayReader CharArrayWriter C:操作字符串 StringReader StringWriter
打印流(掌握)
1、字節打印流 PrintStream,字符打印流 PrintWriter 2、特點: A:只操作目的地,不操作數據源(只能寫不能讀) B:可以操作任意類型的數據 C:如果啟用了自動刷新,在調用println()方法的時候,能夠換行並刷新 D:可以直接操作文件 問題:哪些流可以直接操作文件呢? FileInputStream FileOutputStream FileReader FileWriter PrintStream PrintWriter 流分為基本流(能直接讀寫文件)和高級流(在基本流基礎上提供一些其它功能) 看API,如果其構造方法能夠同時接收File和String類型的參數,一般都是可以直接操作文件的 3、復制文本文件 BufferedReader br = new BufferedReader(new FileReader("a.txt")); PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true); //第二參數啟動刷新 String line = null; while((line=br.readLine())!=null) { pw.println(line); //println自動刷新功能 } pw.close(); br.close();
標準輸入輸出流(理解)
1、System類下面有這樣的兩個字段 in 標準輸入流 out 標準輸出流 2、三種鍵盤錄入方式 A:main方法的args接收參數 B:System.in通過BufferedReader進行包裝 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); C:Scanner Scanner sc = new Scanner(System.in); 3、輸出語句的原理和如何使用字符流輸出數據 A:原理 System.out.println("helloworld"); PrintStream ps = System.out; ps.println("helloworld"); B:把System.out用字符緩沖流包裝一下使用 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
隨機訪問流(理解)
RandomAccessFile類不屬於流,是Object類的子類。 但它融合了InputStream和OutputStream的功能。 支持對文件的隨機訪問讀取和寫入。 1、可以按照文件指針的位置寫數據和讀數據。 2、案例: A:創建隨機訪問流對象 RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw"); //第一個參數是文件路徑,第二個參數是操作文件的模式。 //模式有四種,我們最常用的一種叫"rw",這種方式表示我既可以寫數據,也可以讀取數據 B:寫數據 raf.writeChar(‘a‘); C:讀數據 char ch = raf.readChar(); D:獲取和改變文件指針的位置 raf.getFilePointer(); E:設置指針位置 raf.seek(4);
合並流(理解)
1、把多個輸入流的數據寫到一個輸出流中。 2、構造方法: A:SequenceInputStream(InputStream s1, InputStream s2) B:SequenceInputStream(Enumeration<? extends InputStream> e) 3、例子: public class SequenceInputStreamDemo2 { public static void main(String[] args) throws IOException { // 需求:把下面的三個文件的內容復制到Copy.java中 // ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java // SequenceInputStream(Enumeration e) // 通過簡單的回顧我們知道了Enumeration是Vector中的一個方法的返回值類型。 // Enumeration elements() Vector v = new Vector(); InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java"); InputStream s2 = new FileInputStream("CopyFileDemo.java"); InputStream s3 = new FileInputStream("DataStreamDemo.java"); v.add(s1); v.add(s2); v.add(s3); Enumeration en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("Copy.java")); // 如何寫讀寫呢,其實很簡單,你就按照以前怎麽讀寫,現在還是怎麽讀寫 byte[] bys = new byte[1024]; int len = 0; while ((len = sis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); sis.close(); } }
序列化流(理解)
1、可以把對象寫入文本文件或者在網絡中傳輸。對象 -- 流數據(ObjectOutputStream) 2、如何實現序列化呢(NotSerializableException:未序列化異常)? implements Serializable 讓被序列化的對象所屬類實現序列化接口。 該接口是一個標記接口。沒有功能需要實現。 3、註意問題(InvalidClassException): 把數據寫到文件後,在去修改類,不寫再讀,會產生一個問題。 如何解決該問題呢? 實際開發中,需要修改類但還需要使用以前寫過的數據,不能重新寫入。怎麽辦呢? 在類文件中,給出一個固定的序列化id值。 點擊黃色警告線 Add generated serial version ID, 這樣也可以解決黃色警告線問題 我一個類中可能有很多的成員變量,有些我不想進行序列化。請問該怎麽辦呢? 使用transient關鍵字聲明不需要序列化的成員變量(private transient int age;) 4、面試題: 什麽時候序列化? 如何實現序列化? 什麽是反序列化? 反序列化流:把文本文件中的流對象數據或者網絡中的流對象數據還原成對象。流數據 -- 對象(ObjectInputStream)
Properties(理解)
1、 屬性集合類。是一個可以和IO流相結合使用的集合類。 可保存在流中或從流中加載。屬性列表中每個鍵及其對應值都是一個字符串。 是Hashtable的子類,說明是一個Map集合。 Properties prop = new Properties(); // 添加元素 prop.put("it002", "hello"); prop.put("it001", "world"); prop.put("it003", "java"); // System.out.println("prop:" + prop); // 遍歷集合 2、特有功能 A:public Object setProperty(String key,String value); //添加元素 B:public String getProperty(String key); //獲取元素 C:public Set stringPropertyNames(); //獲取所有鍵的集合 D:例子 public class PropertiesDemo2 { public static void main(String[] args) { // 創建集合對象 Properties prop = new Properties(); // 添加元素 prop.setProperty("張三", "30"); prop.setProperty("李四", "40"); prop.setProperty("王五", "50"); // public Set stringPropertyNames():獲取所有的鍵的集合 Set set = prop.stringPropertyNames(); for (String key : set) { String value = prop.getProperty(key); System.out.println(key + "---" + value); } } } 3、和IO流結合的方法 把鍵值對形式的文本文件內容加載到集合中 public void load(Reader reader) public void load(InputStream inStream) 把集合中的數據存儲到文本文件中 public void store(Writer writer,String comments) public void store(OutputStream out,String comments) 註意:這裏的集合指的是properties集合 例子: public class PropertiesDemo3 { public static void main(String[] args) throws IOException { // myLoad(); myStore(); } private static void myStore() throws IOException { // 創建集合對象 Properties prop = new Properties(); prop.setProperty("林青霞", "27"); prop.setProperty("武鑫", "30"); prop.setProperty("劉曉曲", "18"); //public void store(Writer writer,String comments):把集合中的數據存儲到文件 Writer w = new FileWriter("name.txt"); prop.store(w, "helloworld"); w.close(); } private static void myLoad() throws IOException { Properties prop = new Properties(); // public void load(Reader reader):把文件中的數據讀取到集合中 // 註意:這個文件的數據必須是鍵值對形式 Reader r = new FileReader("prop.txt"); prop.load(r); r.close(); System.out.println("prop:" + prop); } } 4、案例: A:根據給定的文件判斷是否有鍵為"lisi"的,如果有就修改其值為100 B:寫一個程序實現控制猜數字小遊戲程序不能玩超過5次
NIO(了解)
1、JDK4出現的NIO,對以前的IO操作進行了優化,提高了效率。但是大部分我們看到的還是以前的IO。 2、JDK7的NIO的使用 Path:路徑 Paths:通過靜態方法返回一個路徑 public static Path get(URI uri) Files:提供了常見的功能 復制文件: public static long copy(Path source,OutputStream out) 把集合中的數據寫到文本文件: public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options) 3、例子: public class NIODemo { public static void main(String[] args) throws IOException { // public static long copy(Path source,OutputStream out) // Files.copy(Paths.get("ByteArrayStreamDemo.java"), new // FileOutputStream( // "Copy.java")); ArrayList array = new ArrayList(); array.add("hello"); array.add("world"); array.add("java"); Files.write(Paths.get("array.txt"), array, Charset.forName("GBK")); } }
IO流(四)