JAVA高级应用之序列化与反序列化与IO流总结
2018-02-01 22:48
495 查看
缓冲流 序列化 反序列化
缓冲流
字节缓冲流
缓冲流(高效率的流) BufferedOutputStream 缓冲输出字节流 构造方法: BufferedOutPutStream(OutputStream out) 参数:字节输出流的父类 FileOutputStream 你想对哪个流高效 就把该流装进去 BufferedInputStream 缓冲输入字节流
代码示例
// 关闭流的时候 关闭最外层的流即可 // 从文件中读出来的诗歌字节数组,需要转为字符串输出才能看的懂 public class p01 { public static void main(String[] args) throws IOException { FileOutputStream fis = new FileOutputStream("/Users/lanou/Desktop/test/znb.txt"); BufferedOutputStream bos = new BufferedOutputStream(fis); bos.write("窗前明月光".getBytes()); bos.close(); FileInputStream fos = new FileInputStream("/Users/lanou/Desktop/test/znb.txt"); BufferedInputStream bis = new BufferedInputStream(fos); int len = 0; byte[] bs = new byte[1024]; while((len = bis.read(bs)) != -1) { System.out.println(new String(bs, 0, len)); } bis.close(); } }
测试高效流的复制文件快慢
采用缓冲流单字节复制文件与不采用缓冲流单字节复制文件时间比较package com.lanou3g.bean; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.omg.CORBA.PUBLIC_MEMBER; public class p01 { public static void main(String[] args) throws IOException { double d = (new MyClass1().printTime() / new MyClass2().printTime()); System.out.println(d); } } abstract class TestTime{ public long printTime() throws IOException { long start = System.currentTimeMillis(); copyFile(); long end = System.currentTimeMillis(); System.out.println(end - start); return end - start; } public abstract void copyFile() throws IOException; } // 不用缓冲流 单字节读取 class MyClass1 extends TestTime{ @Override public void copyFile() throws IOException { File file1 = new File("/Users/lanou/Desktop/图7.png"); File file2 = new File("/Users/lanou/Desktop/test3/图7.png"); FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); int len = 0; while((len = fis.read()) != -1) { fos.write(len); } fis.close(); fos.close(); } } // 用缓冲流 单字节读取 class MyClass2 extends TestTime{ @Override public void copyFile() throws IOException { File file1 = new File("/Users/lanou/Desktop/图7.png"); File file2 = new File("/Users/lanou/Desktop/XTest/图7.png"); FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int len = 0; while((len = bis.read()) != -1) { bos.write(len); } bis.close(); bos.close(); } }
结果: 15716 321 48.0 即用不用缓冲流复制6.9M的图片用的时间是用缓冲流复制所用时间的48倍
用缓冲流的字节数组读取与复制
package com.lanou3g.bean; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class p02 { public static void main(String[] args) throws IOException { double d = (new MyClass1().printTime() / new MyClass2().printTime()); System.out.println(d); } } abstract class TestTime1{ public long printTime() t 4000 hrows IOException { long start = System.currentTimeMillis(); copyFile(); long end = System.currentTimeMillis(); System.out.println(end - start); return end - start; } public abstract void copyFile() throws IOException; } //不用缓冲流字节数组读取 class MyClass3 extends TestTime1{ File file1 = new File("/Users/lanou/Desktop/图7.png"); File file2 = new File("/Users/lanou/Desktop/test3/图7.png"); @Override public void copyFile() throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); int len = 0; byte[] bs = new byte[1024]; while((len = fis.read(bs)) != -1) { fos.write(bs, 0, len); } fis.close(); fos.close(); } } //用缓冲流字节数组读取 class MyClass4 extends TestTime1{ File file1 = new File("/Users/lanou/Desktop/图7.png"); File file2 = new File("/Users/lanou/Desktop/XTest/图7.png"); @Override public void copyFile() throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int len = 0; byte[] bs = new byte[1024]; while((len = bis.read(bs)) != -1) { bos.write(bs, 0, len); } fis.close(); fos.close(); } }
结果受主机性能影响 结果: 14670 148 99.0
字符缓冲流
BufferedWriter 构造方法: 参数:Writer(父类) 可传:FileWriter OutputStreamWriter 特有方法: newLine() 平台无关性 mac \n Windows /r/n BufferedReader
代码示例
package com.lanou3g.bean; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class p04 { public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("/Users/lanou/Desktop/test3/ppp.txt"); BufferedWriter bw = new BufferedWriter(fw); bw.write("窗前明月光"); bw.newLine(); // 写文件时特有的换行符 bw.flush(); bw.write("疑是地上霜"); bw.flush(); bw.close(); FileReader fr = new FileReader("/Users/lanou/Desktop/test3/ppp.txt"); BufferedReader br = new BufferedReader(fr); String string = null; while((string = br.readLine()) != null) { System.out.println(string); } br.close(); } }
结果:
窗前明月光 疑是地上霜 这里换行了,因为是println输出的,自带换行效果,按行读取 是不能把换行读出来的 要想跟原文本一样,需要加上换行来打印
文件复制
package com.lanou3g.bean; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class p03 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("/Users/lanou/Desktop/test3/ppp.txt"); FileWriter fw = new FileWriter("/Users/lanou/Desktop/test3/ppp6.txt"); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); String string = null; while((string = br.readLine()) != null) { bw.write(string); bw.newLine(); //换行 读的时候 读不出换行 需要自己加 bw.flush(); } bw.close(); } }
流总结
1.明确要做什么操作 数据源 数据的目的地 InputStream Reader 写到数据目的地 OutputStream Writer 2.明确要操作的是什么内容 文本 音频 图片 ... 要使用全能流(字节流) 文本(按编码格式写) 使用字符流 3.明确流要在什么设备上使用 文本 网络 4.是否需要提高效率 buffered 缓冲流
Properties集合
父类是Hashtable 作用:Properties是集合中唯一一个能和IO流配合的类 读取和写入时你传入参数 这个参数是字符流可以 是字节流也可以 集合可以保存数据 然后将集合存入文件中 注意:该集合最好使用的key和value都是字符串; 往集合里面添加元素时要使用setProperty(string,string)方法; 使用put方法添加不进去
public static void fun1(){ Properties properties = new Properties(); properties.setProperty("gender","女"); Set<String> set = properties.keySet(); for(String key : set){ System.out.println(key + "=" + properties.getProperty(key)); } }
读取操作
Properties properties = new Properties(); FileReader fr = new FileReader("/Users/lanou/Desktop/test3/ppp.txt"); properties.load(fr); System.out.println(properties); fr.close();
写入操作
Properties properties = new Properties(); properties.setProperty("a","haha"); properties.setProperty("张飞","哈哈哈"); properties.setProperty("b","asd"); FileWriter fw = new FileWriter("/Users/lanou/Desktop/test3/xzb.properties"); // 后缀名 给什么都可以 // 但是按一般写法 使用.properties当做文件的后缀名来表示该文件可以使用Properties类读取 properties.store(fw,""); // 利用Properties类中的方法写入 // 参数二相当于文件的注释 一般什么都不写 // 在properties文件中 可以使用#来写注释 properties.store(fw,""); fw.close();
序列化与反序列化
序列化流与反序列化流 序列化 就是把对象写入到文件中去 反序列化 就是从文件中把对象读取到程序中 ObjectInputStream 反序列化流 ObjectOutputStream 序列化流 静态成员变量是不能进行序列化的 序列化 序列的是对象 静态成员变量是属于类的 序列化相当于把对象持久化了,因为对象保存在文件中 在进行反序列化的时候 需要依赖你的编译文件,如果编译文件不存在,将会抛出ClassNotFoundException 如果没有实现Serializable接口,将会抛出NotSerializableException异常 抛出IOException情况 当进行序列化的时候,产生.class的同时,会产生一个序列化号码,该序列化号码会随着对象一起 写入到文件中去,当进行反序列化的时候会从写入的文件中取出这个序列化号码,与.class中的序列化号码进行比对, 如果两个序列化号码相等,则会成功写出,不会抛出IO异常;但是,如果你在写入文件之后,读取文件之前,对该类进行了修改,比如加一行,或者加个空格, 保存的时候,生产.class文件会重新生产一个序列化号码,这时再读取文件中的对象时,二者的序列化号码就不在相等,会抛出IOException
图形解释
代码示例
package com.lanou3g.bean; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import com.lanou3g.Student; public class p05 { public static void main(String[] args) throws IOException, ClassNotFoundException { FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/XTest/znb.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(new Student("刘",14)); oos.close(); FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/XTest/znb.txt"); ObjectInputStream ois = new ObjectInputStream(fis); Object readObject = ois.readObject(); Student student = (Student)readObject; System.out.println(student); } }
代码练习
/* * 学生类 * 姓名 性别 年龄 空参有参构造 set和get方法 toString方法 键盘录入6个学员信息(格式为 张三,男,25),要求有两个相同的信息,将6个学员信息存入到ArrayList集合中 将存有6个学员信息的ArrayList集合对象写入到文件中 读取文件中的ArrayList对象 对集合中的6个学生对象进行去重并按照年龄从小到大的顺序排序 再将排序完成的集合写进重新写进文件中 */
package com.lanou3g; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; import java.util.TreeSet; public class Demo08 { public static void main(String[] args) throws IOException, ClassNotFoundException { Scanner scanner = new Scanner(System.in); ArrayList< Student> array = new ArrayList<>(); while(array.size() < 6) { boolean b = true; System.out.println("请输入六个学员信息((格式为 张三,男,25)):"); String string = scanner.nextLine(); try { String[] strings = string.split(","); Student student = new Student(strings[0],strings[1],Integer.parseInt(strings[2])); array.add(student); }catch (ArrayIndexOutOfBoundsException e) { System.out.println("角标越界了 请重新输入"); }catch (Exception e) { System.out.println("年龄不对 请重新输入"); } } FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/p001.txt"); ObjectOutputStream oss = new ObjectOutputStream(fos); oss.writeObject(array); FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/test/p001.txt"); ObjectInputStream ois = new ObjectInputStream(fis); Object readObject = ois.readObject(); array = (ArrayList)readObject; TreeSet<Student> set = new TreeSet<>(); set.addAll(array); System.out.println("+++++"); System.out.println(set); array.clear(); array.addAll(set); oss.writeObject(array); Object readObject2 = ois.readObject(); array = (ArrayList)readObject2; System.out.println(array); oss.close(); ois.close(); } }
package com.lanou3g; import java.io.Serializable; public class Student implements Serializable,Comparable<Student>{ /** * */ private static final long serialVersionUID = 1L; private String name; private String gender; private int age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, String gender, int age) { super(); this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "[name=" + name + ", gender=" + gender + ", age=" + age + "]"; } @Override public int compareTo(Student o) { // TODO Auto-generated method stub boolean b = (this.age == o.getAge() && this.name.equals(o.getName()) && this.gender.equals(o.getGender())); int num = this.age - o.getAge(); if(b == true) { return 0; }else { return num == 0 ? 1 : num; } } }
相关文章推荐
- 文章标题 Java中io流的一些简单操作(包含文件复制,向硬盘中写入文本文件,以及io流高级应用序列化和反序列化)
- JAVA高级应用第六周代码总结
- JAVA高级应用第四周代码总结
- java编程之——IO流应用总结
- JAVA高级应用之IO流及应用
- JAVA高级应用之异常类与IO流
- 今天无意中发现JavaBean类基本都要求实现了Serializable接口,以前只是知道序列化以后,可以通过io流的方式将对象序列化和反序列化,进行存取,但不知道为什么需要序列化,今天总结一下
- 黑马程序员 Java基础知识总结-IO流(应用总结)
- 【Java高级应用】对象序列化和反序列化
- 理解Java对象序列化及其高级应用
- java、IO流总结及应用
- 黑马程序员--Java面向对象——IO流 总结应用(打印流)
- Java基础学习IO流之序列化的总结与归纳
- JAVA高级应用之IO流与文件的处理
- JAVA | 50 - IO 高级应用 | 对象序列化
- 黑马程序员 Java面向对象——IO流 总结应用(打印流)
- Java面向对象——IO流 总结应用(打印流)
- 【北京招聘】(高级)应用软件工程师(Java/C/C++)
- 基础入门:关于JavaIO流学习总结
- Java Annotation 高级应用