【javase复习】## day11 其他流 ##

序列流 SequenceInputStream

如果要实现多个文件的合并,怎么办?
没有序列流之前,想法是为每个文件创建各自的输入流, 然后将这些输入流放入集合中, 创建唯一一个输出流, 遍历读取。

但是JAV提供了序列流来做这个事情,更方便啦。

SequenceInputStream :
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

直接看着定义写了一个小片段。。

public static void main(String[] args) throws IOException {
        File inFile1= new File("E:\\a.txt");
        File inFile2= new File("E:\\b.txt");
        File outFile= new File("E:\\c.txt");

        FileInputStream fis1 =new FileInputStream(inFile1);
        FileInputStream fis2 =new FileInputStream(inFile2);
        FileOutputStream fos =new FileOutputStream(outFile);

        SequenceInputStream sis =new SequenceInputStream(fis1,fis2);
        byte[] buf =new byte[1024];
        int length;

        while((length=sis.read(buf))!=-1)
            fos.write(buf, 0, length);
    }
    sis.close();;//其实没有读写能力, 就是把传入参数的流关闭
    fos.close();

然后我打开文档看一下这个序列流。。。发现他的构造方法有点蛋疼

这里写图片描述

注意,只要构造方法需要InputStream的参数,显然这个流没有读写能力,只是把传入的流进行一些封装。 所以关闭这个流就等于关闭2个inputStream流啦

要么只能合并2个, 要么就要用什么enumeration。。。。那是vector里的东西吧。。我都不怎么记得了。。

回忆一下。

Vector的elements方法返回一个Enumeration类的迭代器。

这个迭代器有hasMoreElements() nextElement()两个方法。。

public static void main(String[] args) throws IOException {
        File inFile1= new File("E:\\a.txt");
        File inFile2= new File("E:\\b.txt");
        File inFile3= new File("E:\\c.txt");
        File outFile= new File("E:\\d.txt");

        FileInputStream fis1 =new FileInputStream(inFile1);
        FileInputStream fis2 =new FileInputStream(inFile2);
        FileInputStream fis3 =new FileInputStream(inFile3);
        FileOutputStream fos =new FileOutputStream(outFile);

        Vector v =new Vector();
        v.addElement(fis1);
        v.addElement(fis2);
        v.addElement(fis3);
        Enumeration e =v.elements();



        SequenceInputStream sis =new SequenceInputStream(e);
        byte[] buf =new byte[1024];
        int length;

        while((length=sis.read(buf))!=-1)
            fos.write(buf, 0, length);
    }

注意::

可以用读写去切割合并音频,但是视频不行。

因为视频的二进制文件有规定的10101010作为起始终止符。。你切刀中间没有终止符,他不是一个正常的视频文件 懂吗!!









对象的输出流 ObjectOutputStream

把对象的信息写到硬盘上, 称为对象的序列化

对于对象的输出流,一看构造方法, 需要传入一个输出流当做参数,显然的,这个流本身也没有读写能力,是借助参数的流的读写能力。。

于是写了一个小DEMO

class Us {
    String name ; 
    String password;

    public Us(String name , String password){
        this.name= name;
        this.password =password;
    }

    public String toString(){
        return this.name+this.password;
    }
}


public class sss {
    public static void main(String[] args) throws IOException {
         File dest = new File("E:\\a.txt");
         FileOutputStream fos = new FileOutputStream(dest);
         ObjectOutputStream oos = new ObjectOutputStream(fos);
         Us luo = new Us("cxksren","atfield321");
         oos.writeObject(luo);
         oos.close();
    }

居然报错。。。

Exception in thread "main" java.io.NotSerializableException: cn.Us
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at cn.sss.main(sss.java:34)

再返回文档看类的说明,
发现有解释::
只能将支持 java.io.Serializable 接口的对象写入流中。
再打开这个接口。。。发现啥方法都没有。。。
原来只是一个标志接口。。。。。实现下就好了






对象的输入流 ObjectInputStream

把文件中对象的信息读取出来, 称为对象的反序列化!!

同样的一看构造方法, 需要传入参数的输入流, 和对象的输出流一样。。

class Us implements Serializable {
    String name ; 
    String password;

    public Us(String name , String password){
        this.name= name;
        this.password =password;
    }

    public String toString(){
        return this.name+" "+this.password;
    }
}


public class sss {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
         File dest = new File("E:\\a.txt");
         FileOutputStream fos = new FileOutputStream(dest);
         ObjectOutputStream oos = new ObjectOutputStream(fos);
         Us luo = new Us("cxksren","atfield321");
         oos.writeObject(luo);
         oos.close();

         FileInputStream fis = new FileInputStream(dest);
         ObjectInputStream ois = new ObjectInputStream(fis);
         System.out.println((Us)ois.readObject());//返回一个对象,但是并没有用到构造方法。  但是创建对象起码要依赖class文件!!
         ois.close();
    }
}

对象输入输出流要注意的细节:
1. 如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口。 Serializable接口没有任何的方法,是一个标识接口而已。
2. 对象的反序列化创建对象的时候并不会调用到构造方法的、
3. serialVersionUID 是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名、成员、包名、工程名算出的一个数字。
4. 使用ObjectInputStream反序列化的时候,ObjeectInputStream会先读取文件中的serialVersionUID,然后与本地的class文件的serialVersionUID进行对比,如果这两个id不一致,那么反序列化就失败了。
5. 如果序列化与反序列化的时候可能会修改类的成员,那么最好一开始就给这个类指定一个serialVersionUID,如果一类已经指定的serialVersionUID,然后
在序列化与反序列化的时候,jvm都不会再自己算这个 class的serialVersionUID了。
6. 如果一个对象某个数据不想被序列化到硬盘上,可以使用关键字transient修饰。
7. 如果一个类维护了另外一个类的引用,那么另外一个类也需要实现Serializable接口。










Properties类生成配置文件

属于Map体系

因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。

用load 如果存的时候有中文, 要用字符流去存, 不然用的IOS8859-1 存中文, 会有乱码

public static void main(String[] args) throws IOException  {
         Properties p1 =new Properties();   
         Properties p2 =new Properties();   //Properties 是继承HashMap的集合 只是一个集合 并不是配置文件
         p1.setProperty("cxksren", "atfield321");
         p1.setProperty("zjl", "19950209");
         p1.setProperty("luoyi", "sb");
         p1.setProperty("傻逼", "白痴");
         p1.store(new FileWriter(new File("E:\\p.properties")), "aloha~"); //把集合的内容写到文件里面去
                                                                           //生成了配置文件

         p2.load(new FileReader("E:\\p.properties"));                   //又用一个集合读取了配置文件的信息
         Set<Entry<Object, Object>> entrys =  p2.entrySet();
         for(Entry<Object, Object> entry: entrys )
             System.out.println(entry.getKey()+"  "+entry.getValue());

         p2.setProperty("傻逼", "周锦岚");   //想修改配置文件的内容,实际这一步只修改了装有读取了配置文件内容的集合
         p2.store(new FileWriter(new File("E:\\p.properties")), "aloha1~");   //重新修改了文件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值