[源码]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个区别:
  1. ByteArrayOutputStream  存的是byte[]  
  2. 具有 write到其他OutputStream 的方法 
  3. 还有就是没有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 压缩流的主要内容,如果未能解决你的问题,请参考以下文章

95-872-050-源码-CEP-CEP之模式流与运算符

设计模式 结构型模式 -- 适配器模式(概述类适配器模式对象适配器模式适配器模式适用场景JDK源码解析(I / O流))

根据IO流源码深入理解装饰设计模式使用

JAVA 同时新建输入流对象和输出流对象,但是写入数据的时候文件被清空

JDK源码:FileOutputStream

IO-转换流