[源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流相关的知识,希望对你有一定的参考价值。
1.对象流
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectStreamDemo implements Serializable {
public static void main(String[] args) {
test3();
}
class Person implements Serializable {
String name = "";
int score = 0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Person [name=" + name + ", score=" + score + "]";
}
}
/**
* 向 一个文本文件中写入一个对象
*/
private static void test1() {
File file = new File("./PerObjectStoreTxt.txt");
FileOutputStream fos = null;
// 创建 ObjectOutputStream 构造器中传入一个OutputStream对象
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(file);
// 创建 ObjectOutputStream 构造器中传入一个OutputStream对象
oos = new ObjectOutputStream(fos);
oos.writeObject(new ObjectStreamDemo().new Person());
Person p2 = new ObjectStreamDemo().new Person();
p2.setName("张三");
p2.setScore(100);
oos.writeObject(p2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (oos != null)
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 从一个文本文件 读取多个对象
*
* @throws
*/
private static void test2() {
File file = new File("./PerObjectStoreTxt.txt");
Person p1;
Person p2;
InputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
p1 = (Person) ois.readObject();
p2 = (Person) ois.readObject();
System.out.println(p1);
System.out.println(p2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ois != null)
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 完成 对象的深克隆
*/
private static void test3() {
Person p1=new ObjectStreamDemo().new Person();
String pName =new String("张三");//最终看这个东西的指向是否还一样
p1.setName(pName);
/**
*由此可以看出 ByteArrayiostream 还是有点用的 主要就是继承IOStream这点
* 有了这点 这个东西 就分别可以作为 ObjectIIOStream的构造器参数传入
* 因为 ObjectInputStream(InputStream is) ObjectOutputStream(OutputStream)
* 他俩就提供 这么 两个东西
*/
ByteArrayOutputStream baos =null;
ByteArrayInputStream bais=null;
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
try {
baos=new ByteArrayOutputStream();
oos=new ObjectOutputStream(baos);
oos.writeObject(p1);
/**
*如何完成 ByteArrayOutputStream 和ByteArrayInputStream 东西的交互?
*
* 实际上这两个东西 只是继承的东西不一样 底层其他基本一样:
* 实际上 这两个东西 都要 自己手动支取:
* ByteArrayOutputStream() 写进去数组还能 用toString toByteArray拿出来
* ByteArrayInputStream(byte[] b) 还需要传byte[]进去 ,可见这个东西古老
*/
bais=new ByteArrayInputStream(baos.toByteArray());
ois=new ObjectInputStream(bais);
//获取深克隆
Person p2=(Person)ois.readObject();
System.out.println(p2);
//修改 克隆对象里边的 成员对象
p2.name="lisi";
//看原对象的 成员对象是否更改
System.out.println(p1);
//再看 这个被克隆的对象 是否被更改
System.out.println(p2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.内存流 /数组流 :
其实就是一个纯数组操作!
这个东西 和AbstractStringBuilder 区别不大 ,就这么3个区别:
- ByteArrayOutputStream 存的是byte[]
- 具有 write到其他OutputStream 的方法
- 还有就是没有CAPACITY
public class ByteArrayOutputStream extends OutputStream{
protected byte buf[];
protected int count;
//ByteArray写入流有两个 构造器 传入默认的数组容量参数
//而ByteAarry写出流 因为一旦放进去 就不允许更改,所以只有一个传byte[]
public ByteArrayOutputStream() {
this(32);
}
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
public synchronized void write(int b) {
int newcount = count + 1;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[count] = (byte)b;
count = newcount;
}
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
int newcount = count + len;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(b, off, buf, count, len);
count = newcount;
}
public synchronized void writeTo(OutputStream out) throws IOException {
//重新 写入新的 输出流 这个类这么一搞算是废了
out.write(buf, 0, count);
}
public synchronized void reset() {
count = 0;
}
public synchronized byte toByteArray()[] { //这写法6
return Arrays.copyOf(buf, count);
}
public synchronized int size() {
return count;
}
public synchronized String toString() {
return new String(buf, 0, count);
}
public synchronized String toString(String charsetName)
throws UnsupportedEncodingException
{
return new String(buf, 0, count, charsetName);
}
public synchronized String toString(int hibyte) {
return new String(buf, hibyte, 0, count);
}
//这个 两个流是直接 写入内存的 内存管理 会进行回收处理
//所以不需要手动关流 这个 close()方法也就是空的
public void close() throws IOException {
}
}
所以说这个东西最大的作用就是ByteArrayOutputStream 和ByteArrayInputStream 分别是OutputStream 和InputStream 的子类 如果要用到对象流传进去会方便一些。
如果说要把 ByteArrayOutputStream的东西拿出来 两招 直接toString() 或者说 getBytes()
3.压缩流
压缩流 是用来 把一个文件 写进一个压缩包里。
这个流 不在 io包下 它是在 java.util.zip
如果我们要传输一个较大的文件 那么就要使用压缩技术
简单传达一下 这里边的东西 :就这么三个东西
ZipInputStream 解压工具
ZipOutputStream 压缩工具
ZipEntry代表的是压缩包中的一个文件实体。
如何压缩文件
直接用ZipIO流去包装IO流
比如说直接用ZipOutputStream 去包装 FileOutputStream 对象
package ZipOutputStreamDemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipOutputStreamDemo {
public static void main(String[] args) {
test1();
}
/**
* 创建 .zip文件 把这个文件封装到ZipFile对象里 直接用ZipOutPutStream 把要写的文件写进去就OK了
*/
// 把文件 1.txt demo.class 实例.PNG 写入 压缩包 one.zip
private static void test1() {
File zipFile = new File("C:/Users/zongjihengfei/Desktop/one.rar/");
// 无论存在与否 先把它创建出来
try {
zipFile.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
FileOutputStream fos = null;
ZipOutputStream zos = null;
// 拿到 一个文件
File file = new File("./1.txt");
// 用 文件输入流 去获取把 文件内容 读取进来
FileInputStream fis = null;
try {
fos = new FileOutputStream(zipFile);
// ZipOutputStream(OutputStream os)
zos = new ZipOutputStream(fos);
fis = new FileInputStream(file);
int hasRead = 0;
/**
* ZipOutputStream 对象 是由文件条目构成的 也就是说 你每添加一个条目 再往里边写 写的内容就是给这个条目
*
* 条目 文件名 在 new ZipEntry(String Name)写上 条目内容 每添加一个条目就写哪个文件
*/
zos.putNextEntry(new ZipEntry(file.getName())); //首先要增加条目才能往这个条目里边写
byte[] b = new byte[1024]; //最大吞吐量
while ((hasRead = fis.read(b)) != -1) {
zos.write(b, 0, hasRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
zos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
以上是关于[源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流的主要内容,如果未能解决你的问题,请参考以下文章
设计模式 结构型模式 -- 适配器模式(概述类适配器模式对象适配器模式适配器模式适用场景JDK源码解析(I / O流))