您的位置:首页 > 编程语言 > Java开发

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;
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息