I/O流
-
流的概念
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象,即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
根据处理数据类型的不同,流分为:字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。
结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
流的类图结构
-
字节流
- 字节输入流
1 public void m1() throws IOException { 2 3 //1.创建文件字节输入流对象 4 InputStream in = new FileInputStream("G:\\testInWord.txt"); 5 6 //2.创建一个字节数组来存放读取到的数据 7 byte []buf = new byte[10];//读10个字节 8 9 //3..通过输入流对象读取数据 10 in.read(buf); 11 12 //4.将字节流转为字符串显示 13 String string= new String(buf); 14 System.out.println(string); 15 16 //5.关闭流 17 in.close(); 18 }
-
- 字节输出流
1 public void m1() throws IOException { 2 3 //1.创建文件字节输出流对象 4 //第一个参数表示输出的路径 5 //第二个参数表示文本的追加方式,如果为ture,那这次输出的数据追加在目标文件里的数据的后面,如果没有会覆盖文件中原来的数据 6 OutputStream out = new FileOutputStream("G:\\testOutWord.txt",true); 7 8 //2准备输出的数据 9 String str = "这是要输出的数据"; 10 11 //3.通过输出流对象输出数据 12 out.write( str.getBytes()); 13 14 //4.将数据刷出 15 out.flush(); 16 17 //关闭数据 18 out.close(); 19 } 20
-
- 缓冲字节输入流
1 //带缓存的输入流 2 public void m2() throws IOException { 3 //1.创建文件输入流对象 4 InputStream in = new FileInputStream("G:\\testWord.txt"); 5 6 //2.堆输入流对象进行封装 7 BufferedInputStream bin = new BufferedInputStream(in); 8 9 //3.创建一个字节数组用于装每一字读取到的数据 10 byte []buf = new byte[10]; 11 String str = ""; 12 13 //循环读取数据直到文件中的数据被读取完 14 while(bin.read(buf) != -1 ) {//判断是否以读取到末尾 15 str += new String(buf); //将每一次到到的连接到上一次的末尾 16 } 17 18 System.out.println(str); 19 20 bin.close();//先关闭内部打开的 21 in.close();//先开的最后关 22 }
-
- 缓冲字节输出流
1 //带缓存的字节输出流,用于大文件 2 public void m2() throws InterruptedException, IOException { 3 4 //1.创建一个文件字节输出流对象 5 OutputStream out = new FileOutputStream("G:\\testOutWord.txt",true); 6 7 //对象输出流进行封装 8 BufferedOutputStream bout = new BufferedOutputStream(out); 9 10 //准备要封装的数据 11 byte []buf = {'a','b','c'}; 12 13 //每隔一秒输出一个字节 14 for( int i = 0; i < buf.length; i++ ) { 15 Thread.sleep(1000); 16 bout.write(buf[i]);//输出数据 17 } 18 19 //将数据刷出 20 bout.flush(); 21 22 //关闭流 23 bout.close(); 24 out.close(); 25 }
-
字符流
- 字符输入流
1 public void m1() throws IOException { 2 3 //创建一个字符输入流对象 4 Reader in = new FileReader("G:\\testOutWord.txt"); 5 6 //准备一个字符数组 7 char[] cbur = new char[10]; 8 9 String str =""; 10 //循环读取数据直到末尾 11 while( in.read(cbur) != -1) { 12 str += new String(cbur); 13 } 14 //读取数据并转到数组中 15 // in.read(cbur);//这是有限读取 16 17 //显示读取到的数据 18 // String str = new String(cbur); 19 System.out.println(str); 20 21 in.close(); 22 23 }
-
- 字符输出流
1 public void m1() throws IOException { 2 3 //创建文件字符输出流对象 4 Writer out = new FileWriter("G:\\testOutWord.txt",true); 5 6 //2.准备数据 7 String str = "nihao dfjh skdj"; 8 9 //通过数据流输出对象数据流 10 out.write(str); 11 12 out.flush(); 13 14 out.close(); 15 }
-
- 缓存字符输入流
1 public void m1() throws IOException { 2 //1.创建一个字符串输入对象 3 Reader in = new FileReader("G:\\testOutWord.txt"); 4 5 //2.封装符串输入流对象 6 BufferedReader bin = new BufferedReader(in); 7 String str = ""; 8 StringBuffer buffer = new StringBuffer(); 9 10 //3.循环读取文件中的数据 11 while( (str = bin.readLine()) != null ) { 12 buffer.append(str); 13 buffer.append("\n");//每读取一行数据添加一个换行符 14 } 15 16 //4.使用数据 17 System.out.println(buffer.toString()); 18 19 //5. 20 bin.close(); 21 in.close(); 22 } 23
-
对象流
首先建立一个用于序列化和反序列化的类,这里建立一个People类如下:
1 import java.io.Serializable; 2 3 /** 4 * javabean :符合某种规范的类 5 * 1.私有化成员变量 6 * 2.提供get/set方法 7 * 3.实现Serializable接口 8 * 4.必须有共有无参构造器 9 * @author me 10 * 11 */ 12 public class People implements Serializable{ 13 14 private String name; 15 private int age; 16 private char sex; 17 18 19 public People() { 20 super(); 21 } 22 23 public People(String name, int age, char sex) { 24 super(); 25 this.name = name; 26 this.age = age; 27 this.sex = sex; 28 } 29 30 public String getName() { 31 return name; 32 } 33 public void setName(String name) { 34 this.name = name; 35 } 36 public int getAge() { 37 return age; 38 } 39 public void setAge(int age) { 40 this.age = age; 41 } 42 public char getSex() { 43 return sex; 44 } 45 public void setSex(char sex) { 46 this.sex = sex; 47 } 48 49 @Override 50 public String toString() { 51 return "People [name=" + name + ", age=" + age + ", sex=" + sex + "]"; 52 } 53 54 }
-
- 对象序列化(对象输出流)
1 //对象序列化 2 public void m1() throws IOException { 3 4 //创建文件字节输出流对象 5 OutputStream out = new FileOutputStream("G:\\testOutWord.txt"); 6 7 //创建对象输出流 8 ObjectOutputStream obj = new ObjectOutputStream(out); 9 10 //创建实现了Seri接口的类来创建 11 People people = new People("Jake",15,'男'); 12 13 //输出到文件 14 obj.writeObject(people); 15 16 //关闭 17 obj.close(); 18 out.close(); 19 }
-
- 对象反序列化(对象输入流)
1 //反序列化 2 public void m2() throws IOException, ClassNotFoundException { 3 4 InputStream in = new FileInputStream("G:\\testOutWord.txt"); 5 6 ObjectInputStream obj = new ObjectInputStream(in); 7 8 People people = (People) obj.readObject(); 9 10 obj.close(); 11 }
-
- 序列化反序列化的另外一个例子
1 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { 2 3 Person person = new Person("小黑",25);//Person类的代码省略 4 5 //序列化Person 6 ObjectOutputStream oo = new ObjectOutputStream( new FileOutputStream( new File("E:\\newF\\testword.txt"))); 7 oo.writeObject(person); 8 oo.close(); 9 System.out.println("serializa successed!"); 10 11 //反序列化Person 12 ObjectInputStream oi = new ObjectInputStream( new FileInputStream( new File("E:\\newF\\testword.txt"))); 13 Person person2 = (Person) oi.readObject();//需要强转 14 System.out.println(person2); 15 }