io流中比较特殊的流-java

1.序列流(SequenceInputStream)整合个多个文件

A SequenceInputStream表示其他输入流的逻辑级联。 它从一个有序的输入流集合开始,从第一个读取到文件的结尾,然后从第二个文件读取,依此类推,直到最后一个输入流达到文件的结尾。

import java.io.*;
import java.util.Enumeration;
import java.util.Vector;

public class Test8 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis1 = new FileInputStream("a.txt");
        FileInputStream fis2 = new FileInputStream("b.txt");
        FileInputStream fis3 = new FileInputStream("c.txt");
        Vector<FileInputStream> v = new Vector<>();
        v.add(fis1);
        v.add(fis2);
        v.add(fis3);
        Enumeration<FileInputStream> en = v.elements();    // 获取枚举引用
        SequenceInputStream sis = new SequenceInputStream(en);
        FileOutputStream fos = new FileOutputStream("sum.txt");
        int b;
        while ((b = sis.read()) != -1){
            fos.write(b);
        }
        sis.close();
        fos.close();
    }
}

 

2.内存输出流(ByteArrayOutputStream)

该类实现了将数据写入字节数组的输出流。 当数据写入缓冲区时,缓冲区会自动增长。 数据可以使用toByteArray()和toString() 。

一般,读一个文本文件输出到控制台会用字符流而不用字节流。为什么呢?字节流可以读一个字节,或者一个字节数组。首先读一个字节肯定是不可行的,程序读到一个字节,怎么转回一个字符?然后是字节数组,不同的编码格式占字节数是不同的,UTF-8编码下一个中文所占字节也是不确定的,可能是2个、3个、4个字节;所以,字节数组的长度也不知道是多少。

如果一定要用字节流来读一个文本文件,输出到控制台,那么就要用ByteArrayOutputStream了。

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Test9 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
        byte[] arr = new byte[4];
        int len;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((len = fis.read(arr)) != -1){
            baos.write(arr,0,len);
        }
        System.out.println(baos.toString());     // toString()方法可以省略
    }
}

相似的还有ByteArrayInputStream。

 

3.对象操作流(ObjectOutputStream与ObjectInputStream)

  • ObjectOutputStream

将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。只有支持java.io.Serializable接口的对象才能写入流中。 每个可序列化对象的类被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭。方法writeObject用于将一个对象写入流中。 任何对象,包括字符串和数组,都是用writeObject编写的。 多个对象或原语可以写入流。 必须从对应的ObjectInputstream读取对象,其类型和写入次序相同。

 

  • ObjectInputStream

反序列化先前使用ObjectOutputStream编写的原始数据和对象。ObjectOutputStream和ObjectInputStream可以分别为与FileOutputStream和FileInputStream一起使用的对象图提供持久性存储的应用程序。 ObjectInputStream用于恢复先前序列化的对象。 其他用途包括使用套接字流在主机之间传递对象,或者在远程通信系统中进行封送和解组参数和参数。

示例:ObjectOutputStream

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

public class Test10 {
    public static void main(String[] args) throws IOException {
        Person p1 = new Person("张三",13);
        Person p2 = new Person("李四",14);
        ArrayList<Person> list = new ArrayList<>();   // 直接存储p1,p2对象也可以,但是读取的时候,不知道个数,读超了会出现EOFException。所以最好的办法是放在一个集合里,读一次即可
        list.add(p1);
        list.add(p2);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d.txt"));
        oos.writeObject(list);
        oos.close();
    }
}

class Person implements Serializable {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 

示例:ObjectInputStream

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;

public class Test11 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d.txt"));
        ArrayList<Person> list = (ArrayList<Person>) ois.readObject();
        for (Person p: list) {
            System.out.println(p);
        }
        ois.close();
    }
}

 

posted @ 2019-01-16 17:06  苦瓜爆炒牛肉  阅读(324)  评论(0编辑  收藏  举报