java.util跟io_Java学习——IO技术小结(2)

1.对象流小结

为什么需要对象流?

答:数据流只能实现对基本数据类型和字符串类型的读写,并不能读取对象(字符串除外),处理流可以对某个对象进行读写操作。

ObjectInputStream/ObjectOutputStream是以“对象”为数据源,但是必须将传输的对象进行序列化与反序列化操作。

对象流的使用

package cn.sxt.study64;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class object1 {

public static void main(String[] args) {

//write();read();

}

public static void write(){

ObjectOutputStream o1=null;

try {

o1=new ObjectOutputStream(new FileOutputStream("E:/temp64.txt"));

o1.writeObject(new Student1("东方月初",19));

o1.writeInt(98);

o1.writeUTF("涂山");

} catch (FileNotFoundException e) {

// TODO Auto-generated catch blocke.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

} finally{

if(o1!=null){

try {

o1.close();

} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

}

}

}

}

public static void read(){

ObjectInputStream i1=null;

try {

i1=new ObjectInputStream(new FileInputStream("E:/temp64.txt"));

System.out.println((Student1)i1.readObject());

System.out.println(i1.readInt());

System.out.println(i1.readUTF());

} catch (FileNotFoundException e) {

// TODO Auto-generated catch blocke.printStackTrace();

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch blocke.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

}finally{

if(i1!=null){

try {

i1.close();

} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

}

}

}

}

}

package cn.sxt.study64;

import java.io.Serializable;

public class Student1 implements Serializable{

/****/

private static final long serialVersionUID = 1493094980381450161L;

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public Student1(String name, int age) {

super();

this.name = name;

this.age = age;

}

public Student1() {

super();

}

@Override

public String toString() {

return "Student [name=" + name + ", age=" + age + "]";

}

}

2.序列化小结

a.为什么需要序列化?

答:当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何种类型的数据,都会以二进制序列的形式在网络上传送。比如,我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常读取。

b.什么是序列化?

答:把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。对象的序列化需要实现java.lang.Serializible接口

c.对象序列化的作用有如下两种:

1. 持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现。

2. 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。

注意

1.1 序列化与反序列化

1) 序列化能保存的元素

a) 只能保存对象的非静态成员变量

b) 不能保存任何成员方法和静态的成员变量

c) 不保存 transient 成员变量

d) 如果一个对象的成员变量是一个对象,这个对象的成员变量也会保存

e) 串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存

2) 使用对象流把一个对象写到文件时不仅保证该对象是序列化的,而且该对象的成员对象也必须是可序列化的。

3) 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。

1.2 对象序列化注意事项

1) 同一个对象多次序列化的处理

a) 所有保存到磁盘中的对象都有一个序列化编号

b) 序列化一个对象中,首先检查该对象是否已经序列化过

c) 如果没有,进行序列化

d) 如果已经序列化,将不再重新序列化,而是输出编号即可

2) 如果不希望某些属性(敏感)序列化,或不希望出现递归序列

a) 对象中的某些属性如果不想被序列化,不能使用static,而是使用transient修饰。transient参加序列化但不能把值写入。

b) 自定义序列化(不仅可以决定哪些属性不参与序列化,还可以定义属性具体如何序列化)

3) 序列化版本不兼容

a) 修改了实例属性后,会影响版本号,从而导致反序列化不成功

b) 解 决 方 案 : 为 Java 对 象 指 定 序 列 化 版 本 号serialVersionUID

序列化和反序列化的使用:

package cn.sxt.study64;

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;

public class Object3 {

public static void main(String[] args) {

//write();

read();

}

public static void read(){

ObjectInputStream i1=null;

try {

i1=new ObjectInputStream(new FileInputStream("E:/temp643.txt"));

Classes3 c=(Classes3)i1.readObject();

System.out.println(c.getClassName()+c.getAl());

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

if(i1!=null){

try {

i1.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

public static void write(){

ObjectOutputStream o1=null;

try {

o1=new ObjectOutputStream(new FileOutputStream("E:/temp643.txt"));

ArrayList al=new ArrayList();

al.add(new Student1("东方月初",16));

al.add(new Student1("诸葛敏",18));

al.add(new Student1("令狐冲",26));

Classes3 cl=new Classes3("最牛第一班",al);

o1.writeObject(cl);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

if(o1!=null){

try {

o1.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

package cn.sxt.study64;

import java.io.Serializable;

import java.util.ArrayList;

public class Classes3 implements Serializable{

/**

*

*/

private static final long serialVersionUID = -9219941731294650211L;

private String className;

private ArrayList al;

private String address;

public String getClassName() {

return className;

}

public void setClassName(String className) {

this.className = className;

}

public ArrayList getAl() {

return al;

}

public void setAl(ArrayList al) {

this.al = al;

}

public Classes3(String className, ArrayList al) {

super();

this.className = className;

this.al = al;

}

public Classes3() {

super();

}

}

3.文件夹的复制

创建源(起始文件夹,目标文件夹),选择流;

编写文件的复制方法;

再通过递归的方法实现文件夹和子文件夹下所有内容的复制。(主要是递归,遍历文件夹)

package cn.sxt.study64;

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;

public class Copy1 {

public static void main(String[] args) {

File src=new File("E:/路飞1.jpg");//创建源

File target=new File("D:/路飞1.jpg");

fileCopy(src,target);

File src2=new File("C:\\Users\\Administrator\\Desktop\\课程资料");//创建源

File target2=new File("C:/课程资料");

dirCopy(src2,target2);

}

//文件的复制

public static void fileCopy(File srcFile,File targetFile){

BufferedInputStream i1=null;//选择流

BufferedOutputStream o2=null;

try {

i1=new BufferedInputStream(new FileInputStream(srcFile));

FileOutputStream o1=new FileOutputStream(targetFile);

o2=new BufferedOutputStream(o1);

int num=0;

byte[] by=new byte[1024];

while((num=i1.read(by))!=-1){

o1.write(by, 0, num);

}

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

if(o2!=null){

try {

o2.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(i1!=null){

try {

i1.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

public static void dirCopy(File srcDir,File targetDir){

if(!targetDir.exists()){

targetDir.mkdir();

}

File[] f=srcDir.listFiles();

for(File temp:f){

if(temp.isFile()){

fileCopy(new File(srcDir+"/"+temp.getName()),new File(targetDir+"/"+temp.getName()));

}else{

dirCopy(new File(srcDir+"/"+temp.getName()),new File(targetDir+"/"+temp.getName()));

}

}

}

}

4.字节数组流

ByteArrayInutStream 和 ByteArrayOutputStream

1) 数据源或目的地为:字节数组

2) 只有字节流,没有字符流

3) 节点流

作用:ByteArrayInputStream则是把内存中的”某个字节数组对象”当做数据源。提高空间利用率,压缩内容,在网络传输时,能有效压缩传输数据的大小,从而提高效率。

package cn.sxt.study64;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.util.Arrays;

import java.util.Date;

public class Byte1 {

public static void main(String[] args) {

byte[] by1=write();

//System.out.println(Arrays.toString(by1));;

read(by1);

}

public static void read(byte[] by){

ByteArrayInputStream i1=null;

ObjectInputStream i2=null;

try {

i1=new ByteArrayInputStream(by);

i2=new ObjectInputStream(i1);

System.out.println(i2.readObject());

System.out.println(i2.readObject());

System.out.println(i2.readInt());

System.out.println(i2.readDouble());

System.out.println(i2.readBoolean());

System.out.println(i2.readUTF());

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

if(i2!=null){

try {

i2.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

public static byte[] write(){

ByteArrayOutputStream o1=null;

ObjectOutputStream o2=null;

try {

o1=new ByteArrayOutputStream();

o2=new ObjectOutputStream(o1);

o2.writeObject(new Student1("dfa",26));

o2.writeObject(new Date(1000));

o2.writeInt(15);

o2.writeDouble(26.5);

o2.writeBoolean(true);

o2.writeUTF("你好");

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally{

if(o2!=null){

try {

o2.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

return o1.toByteArray();//注意处

}

}

5.设计模式_装饰器模式

作用:动态的为一个对象增加新的功能

简介:装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

优点:

1) 扩展对象功能,比继承灵活,不会导致类个数急剧增加

2) 可以对一个对象进行多次装饰,创建出不同行为的组合,得到功能更加大的对象

3) 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类

缺点:

1) 产生很多小对象。大量小对象占据内存,一定程序上影响性能

2) 装饰模式易于出错,调试排查比较麻烦

class Iphone {

private String name;

public Iphone(String name) {

this.name = name;

}

public void show() {

System.out.println("我是" + name + ",可以在屏幕上显示");

}

}

class TouyingPhone {

public Iphone phone;

public TouyingPhone(Iphone p) {

this.phone = p;

}

// 功能更强的方法

public void show() {

phone.show();

System.out.println("还可以投影,在墙壁上显示");

}

}

public class TestDecoration {

public static void main(String[] args) {

Iphone phone = new Iphone("iphone30");

phone.show();

System.out.println("===============装饰后");

TouyingPhone typhone = new TouyingPhone(phone);

typhone.show();

}

}

IO 流实现细节

(1)抽象构件角色 InputStream,OutputStream,Reader,Writer

(2)具体构件角色 FileInputStream,FileOutputStream

(3)装饰器角色 FilterInputStream,FilterOutputStream

持有一个抽象构件的引用

(4)具体装饰角色

BufferedInputStream,BufferedOutputStream 等

6.Apache IOUtils 的使用_Apache FileUtils的使用

1.IOUtils 与 FileUtils

Commons IO 是 apache 的一个开源的工具包,封装了 IO操作的相关类,使用 Commons IO 可以很方便的读写文件,

(1) FileUtils 中提供了许多设计文件操作的 已封装好的方法。

(2) IOUtils 则是提供了读写文件的方法

2.IOUtils 工具类操作的相关方法

(1)String IOUtils.toString(InputStream input)传入输入流对象返回字符串

3.FileUtils 工具类操作的相关方法

(1)String FileUtils.readFileToString(File file,String encoding)

FileUtils.writeStringToFile(File file,String data,Stringencoding)读写文件

(2)FileUtils.copyFile(File srcFile,File destFile)复制文件

(3)FileUtils.copyURLToFile(URL source,File destination)复制url 对象到指定文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值