IO流(二)I/O
一.IO流概述
1.定义:Java的IO流是实现输入输出的基础,它可以方便地实现数据的输入/输出操作。
2.流的分类:
(1)按流向来分:输入流和输出流
(2)按操作的数据来分:字节流和字符流
(3)按流的角色来分:节点流和处理流
二.IO流类图
常用流分类:
通常来说,字节流的功能比字符流强大,因为计算机里所有的数据都是二进制的,而字节流可以处理所有的二进制文件,但如果使用字节流来处理文本文件,则需要将字节转换为字符,这增加了编程复杂度。所以有这样一个规则:如果操作的内容是文本,则考虑使用字符流,如果操作的内容是二进制内容,则应考虑使用字节流。
三.常用流介绍
1.转换流:输入/输出流体系中还提供了两个转换流,这两个转换流用于实现将字节流转换成字符流。
InputStreamReader将字节输入流转换成字符输入流,OutputStreamWriter将字节输出流转换成字符输出流。
1 public class InputStreamReaderDemo { 2 public static void main(String[] args) { 3 // 将标准字节输入流转换为字符流 4 InputStreamReader reader = new InputStreamReader(System.in); 5 // 将字符流进一步包装成缓冲流 6 BufferedReader buffer = new BufferedReader(reader); 7 String line = null; 8 try { 9 // System.out.println("请输入:"); 10 while ((line = buffer.readLine()) != null) { 11 12 if ("exit".equals(line)) { 13 System.exit(1);// 读取到exit,程序退出 14 } 15 System.out.println("输出内容:" + line); 16 } 17 } catch (IOException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 } 22 }
2.缓冲流
BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedeWriter
使用缓冲流的好处:能够高效的读写信息,原理是先将数据缓存起来,然后再一起写入或者读取出来。
3.打印流
PrintStream,PrintWriter
使用打印流的好处:可以很方便的进行输出
1 public class PrintDemo { 2 3 public static void main(String[] args) { 4 printToFile(); 5 System.out.println("success"); 6 } 7 8 public static void printToFile(){ 9 try { 10 OutputStream output = new FileOutputStream("D:\\code\\999.txt"); 11 PrintWriter pw = new PrintWriter(new BufferedOutputStream(output)); 12 pw.println("我是一只小小小鸟"); 13 pw.println(true); 14 pw.println(999); 15 pw.println(1.114); 16 pw.flush(); 17 pw.close(); 18 } catch (FileNotFoundException e) { 19 e.printStackTrace(); 20 } 21 22 } 23 }
4.对象流:序列化和反序列化对象
(1)什么是对象序列化
对象序列化的目标是将对象保存到磁盘中,或在网络中传输对象。
对象序列化机制允许把内存中的对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点,其他程序一旦获得这个二进制流,就可以将这种二进制流恢复成原来的java对象。
(2)如何让类是可序列化的
实现Serializable接口,该接口是一个标记接口,接口内无任何需要实现的方法。
(3)对象的序列化和反序列化
对象序列化(Serialize)是指将一个java对象写入IO流中,对象的反序列化(Deserialize)是指从IO流中恢复该java对象
(4)怎么使用对象流实现序列化
两个类:ObjectOutputStream,ObjectInputStream 对象流是处理流,需要建立在节点流的基础之上。
两个方法:writeObject(), readObject()
如果不想序列化某个成员变量,可以在声明中加入关键字 transient, 例如private transient int age;
使用方法见下面代码:(Dog类省略)
1 package com.gdp.xuliehua; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.ObjectInputStream; 9 import java.io.ObjectOutputStream; 10 import java.io.OutputStream; 11 12 public class TestDog { 13 public static void main(String[] args) { 14 //writeObject(); 15 //readObject(); 16 //writeObject2(); 17 readObject2(); 18 } 19 /** 20 * 将对象写入到文件中 21 */ 22 public static void writeObject(){ 23 try { 24 OutputStream out = new FileOutputStream("D:\\dog.txt"); 25 ObjectOutputStream oos = new ObjectOutputStream(out); 26 oos.writeInt(130); 27 Dog dog = new Dog("小黑",3); 28 oos.writeObject(dog); 29 oos.flush(); 30 oos.close(); 31 out.close(); 32 System.out.println("OK"); 33 } catch (FileNotFoundException e) { 34 e.printStackTrace(); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 39 } 40 /** 41 * 从文件中读取对象 42 */ 43 public static void readObject(){ 44 try { 45 InputStream in = new FileInputStream("D:\\dog.txt"); 46 ObjectInputStream ois = new ObjectInputStream(in); 47 int i = ois.readInt(); 48 Dog dog = (Dog)ois.readObject(); 49 ois.close(); 50 in.close(); 51 System.out.println(i); 52 System.out.println(dog); 53 } catch (FileNotFoundException e) { 54 e.printStackTrace(); 55 } catch (IOException e) { 56 e.printStackTrace(); 57 } catch (ClassNotFoundException e) { 58 e.printStackTrace(); 59 } 60 61 } 62 /** 63 * 序列化多个对象,采用对象数组来实现将对象写入文件中 64 */ 65 public static void writeObject2(){ 66 Dog dog1 = new Dog("小黑",5); 67 Dog dog2 = new Dog("小白",3); 68 Dog dog3 = new Dog("小红",6); 69 try { 70 OutputStream out = new FileOutputStream("D:\\obj.tmp"); 71 ObjectOutputStream oos = new ObjectOutputStream(out); 72 Dog[] dogs = new Dog[]{dog1,dog2,dog3}; 73 oos.writeObject(dogs); 74 oos.flush();oos.close();out.close(); 75 System.out.println("ok"); 76 } catch (FileNotFoundException e) { 77 e.printStackTrace(); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 } 81 82 83 } 84 /** 85 * 将多个对象从文件中读取出来 86 * 1.读取出来的对象是对象数组 87 * 2.遍历数组,取出对象 88 */ 89 public static void readObject2(){ 90 try { 91 InputStream in= new FileInputStream("D:\\obj.tmp"); 92 ObjectInputStream ois = new ObjectInputStream(in); 93 Dog[] dogs = (Dog[])ois.readObject(); 94 ois.close();in.close(); 95 for (Dog dog : dogs) { 96 System.out.println(dog); 97 } 98 } catch (FileNotFoundException e) { 99 e.printStackTrace(); 100 } catch (IOException e) { 101 e.printStackTrace(); 102 } catch (ClassNotFoundException e) { 103 e.printStackTrace(); 104 } 105 106 } 107 }
5.ByteArrayInputStream和ByteArrayOutputStream
(1)ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。
关闭ByteArrayInputStream无效,此类的方法在关闭流后仍可被调用,而不会产生任何IOException。
(2)ByteArrayOutputStream,此类实现一个输出流,其中的数据被写入一个byte数组,缓冲区会随着数据的不断写入而自动增长,可以使用toByteArray()和toString()获取数据.
关闭ByteArrayOutputStream无效,此类的方法在关闭流后仍可被调用,而不会产生任何IOException。
(3)使用方法如下列代码:
1 import java.io.ByteArrayInputStream; 2 import java.io.ByteArrayOutputStream; 3 import java.io.IOException; 4 5 public class ByteArrayDemo { 6 public static void main(String[] args) { 7 write(); 8 } 9 /** 10 * 写入数据,不与文件关联,写入内存 11 * 读取数据并显示 12 */ 13 public static void write(){ 14 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 15 String info = "我是一只小小小小鸟!"; 16 try { 17 bos.write(info.getBytes()); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 //读取数据 22 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 23 StringBuffer buf = new StringBuffer(); 24 byte[] bytes = new byte[1024]; 25 int temp ; 26 try { 27 while((temp=bis.read(bytes))!=-1){ 28 buf.append(new String(bytes, 0, temp)); 29 } 30 System.out.println(buf.toString()); 31 } catch (IOException e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 } 35 36 } 37 }
6.过滤器数据流:DataInputStream和DataOutputStream
(1)DataInputStream和DataOutputStream专门用于读写基本数据类型数据,而对象流既可以读写基本数据类型的数据也可以读写对象。
(2)它是一个处理流,需要建立在节点流的基础之上,如new DataInputStream(new FileInputStream("text.txt"))
(3)DataInputStream和DataOutputStream有读写的相关方法一一对应,基本使用方法见下面代码:
1 import java.io.DataInputStream; 2 import java.io.DataOutputStream; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.OutputStream; 9 10 public class DataStreamDemo { 11 public static void main(String[] args) { 12 // write(); 13 read(); 14 } 15 16 /** 17 * 向文件写入数据 18 */ 19 public static void write() { 20 try { 21 OutputStream out = new FileOutputStream("D:\\test.txt"); 22 DataOutputStream dos = new DataOutputStream(out); 23 dos.writeInt(100);// 写入int数值 24 dos.writeDouble(99.99);// 写入double数值 25 dos.writeBoolean(true);// 写入boolean值 26 dos.writeUTF("我是一只小小小小鸟"); 27 dos.flush(); 28 dos.close(); 29 out.close(); 30 } catch (FileNotFoundException e) { 31 e.printStackTrace(); 32 } catch (IOException e) { 33 e.printStackTrace(); 34 } 35 36 } 37 38 /** 39 * 从文件读取数据 40 */ 41 public static void read() { 42 try { 43 InputStream in = new FileInputStream("D:\\test.txt"); 44 DataInputStream dis = new DataInputStream(in); 45 System.out.println(dis.readInt()); 46 System.out.println(dis.readDouble()); 47 System.out.println(dis.readBoolean()); 48 System.out.println(dis.readUTF()); 49 } catch (FileNotFoundException e) { 50 e.printStackTrace(); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 55 } 56 }