美文网首页
day22-序列流/内存流/对象操作流/打印流/随机流

day22-序列流/内存流/对象操作流/打印流/随机流

作者: 苦笑男神 | 来源:发表于2017-02-14 19:06 被阅读71次

    22.01_IO流(序列流)(了解)

    序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.

    • 整合两个: SequenceInputStream(InputStream, InputStream)
    FileInputStream fis1 = new FileInputStream("a.txt");
    FileInputStream fis2 = new FileInputStream("b.txt");
    SequenceInputStream sis = new SequenceInputStream(fis1, fis2); //整合2个输入流
    FileOutputStream fos = new FileOutputStream("c.txt"); //输出流
    
    int a ;
    while((a = sis.read()) != -1) {
        fos.write(a);
    }
    
    sis.close();  //sis关闭的时候,会将内部的输入流都关闭掉
    fos.close();
    

    22.02_IO流(序列流整合多个)(了解)

    • 整合多个: SequenceInputStream(Enumeration)
    Vector<FileInputStream> v = new Vector<>();
    v.add(new FileInputStream("a.txt"));
    v.add(new FileInputStream("b.txt"));
    v.add(new FileInputStream("c.txt"));
    // 利用枚举,将多个输入流整合成一个
    SequenceInputStream sis = new SequenceInputStream(v.elements());
    FileOutputStream fos = new FileOutputStream("d.txt");
    int data ;
    while( (data = sis.read()) != -1) {
        fos.write(data);
    }
    
    sis.close();
    fos.close();
    

    22.03_IO流(内存输出流)(掌握)

    该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据

    • 2.使用方式
      • 创建对象: new ByteArrayOutputStream()
      • 写出数据: write(int), write(byte[])
      • 获取数据: toByteArray()
    FileInputStream fis = new FileInputStream("a.txt");
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); //相当于在内存中创建了可以增长的数组
    int b ;
    while( (b = fis.read()) != -1) {
        baos.write(b);  // 此时其实是写数据到了内存里面
    }
    
    byte[] arr = baos.toByteArray(); //将缓冲区的数组全部拿出来, 并赋值给arr数组
    System.out.println(new String(arr));
    System.out.println(baos.toString()); //使用平台默认码表将缓冲区内容转为字符串
    
    fis.close();
    

    22.04_IO流(内存输出流之面试题)(掌握)

    • 定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)
    FileInputStream fis = new FileInputStream("a.txt");      //创建字节输入流,关联a.txt
    ByteArrayOutputStream baos = new ByteArrayOutputStream();   //创建内存输出流
    byte[] arr = new byte[5];      //创建字节数组,大小为5
    int len;
    while((len = fis.read(arr)) != -1) {        //将文件上的数据读到字节数组中
        baos.write(arr, 0, len);   //将字节数组的数据写到内存缓冲区中
    }
    System.out.println(baos);       //将内存缓冲区的内容转换为字符串打印
    fis.close();
    

    22.05_对象操作流ObjecOutputStream(了解)

    该流可以将一个对象写出, 或者读取一个对象到程序中. 也就是执行了序列化反序列化的操作.

    • 写出: new ObjectOutputStream(OutputStream), writeObject()
    //无论是字节输出流,还是字符输出流都不能直接写出对象
    
    Person p1 = new Person("我啊", 20);
    Person p2 = new Person("你啊", 56);
    // 这个其实也是装饰模式
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
    
    oos.writeObject(p1);
    oos.writeObject(p2);
    oos.close();
    

    22.06_对象操作流ObjectInputStream(了解)

    • 读取: new ObjectInputStream(InputStream), readObject()
    // 读取对象(反序列化)
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
    
    Person p1 = (Person) ois.readObject();  //可能有ClassNotFoundException
    Person p2 = (Person) ois.readObject(); //当读取到文件末尾,继续读取,会出现EOFException
    
    System.out.println(p1);
    System.out.println(p2);
    ois.close();
    

    22.07_对象操作流优化(了解)

    // 1.读写多个对象时,将对象添加到集合里,写出集合,就不用考试多少个对象问题
    ArrayList<Person> list = new ArrayList<>();
    list.add(new Person("我啊", 20));
    list.add(new Person("你啊", 56));
    
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
    oos.writeObject(list);
    oos.close();
    
    // 2.读取多个对象
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
    @SuppressWarnings("unchecked")
    ArrayList<Person> aList = (ArrayList<Person>) ois.readObject(); 
    for (Person person : aList) {   //泛型在运行期会被擦除,索引运行期相当于没有泛型
        System.out.println(person);
    }
    ois.close();
    

    关于Java泛型的一点思考

    其实学好、学扎实编程语言的基础,十分重要,对日后编程有十分有帮助。如果你掌握了编程语言的高级语法,基础十分扎实(内功深厚),那么你写出的代码,将比其他人写的代码有水平很多。
    另外就是如果你又扎实深厚的基础,那么也能大大减少日后编程中犯低级错误。

    ArrayList<Integer> l1 = new ArrayList<>();
    l1.add(100);
    
    ArrayList l2 = null;
    l2 = l1;  //泛型擦除 ,证明Java泛型是伪泛型,JVM编译时,并没有核对泛型信息,绕过了类型检查
    从反射也能说明Java泛型,只是编译时有效,运行后会去泛型化
    l2.add("dftd");
    //
    System.out.println(l2.get(0).getClass());
    System.out.println(l2.get(1).getClass());
    System.out.println(l1.size());
    Integer temp = l1.get(1);  //泛型擦除,带来的隐患,报错
    

    22.08_IO流(加上id号)(了解)

    • 要写出的对象必须实现Serializable接口才能被序列化
    • 不用必须加id号
    /**
     * serialVersionUID 序列化版本号,为了序列化时,如果增加了属性,或方法,反序列化之前的版本,能提示出问题所在。
     * 其实不加也行,因为加不加,在反序列老版本对象都会出现异常错误。
     */
    private static final long serialVersionUID = 1L;
    

    22.09_IO流(打印流的概述和特点)(掌握)

    该流可以很方便的将对象的toString()结果输出, 并且自动加上换行, 而且可以使用自动刷出的模式

    System.out就是一个PrintStream, 其默认向控制台输出信息
    
    PrintStream ps = System.out;
    ps.println("xxoo");
    ps.println(97);  // 底层将 数字97 转为了字符串
    
    ps.write(97);  //打印 a
    ps.close();
    ----------------------分割线--------------------
    
    PrintWriter pw2 = new PrintWriter(new FileOutputStream("a.txt"), true);
    pw2.println(97);  // 自动刷出功能,只针对  println() 方法
    pw2.write(97);  // 并不会写到文件里
    
    pw2.close();  // 因为流操作都会要close,所以自定刷出其实没有什么卵用
    
    // PrintStream 和 PrintWriter分别打印的是字节流和字符流
    // 二者只操作数据目的,不操作 数据源
    

    22.10_标准输入输出流概述和输出语句

    • System.inInputStream, 标准输入流, 默认可以从键盘输入读取字节数据
    • System.outPrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据
    • 2.修改标准输入输出流(了解)
    System.setIn(new FileInputStream("a.txt")); //改变标准输入流
    System.setOut(new PrintStream("b.txt"));  //改变标准输出流
    
    InputStream is = System.in;  //此时已经指向文件了,而不是键盘了
    PrintStream ps = System.out;  //此时不再指向控制台,而是b.txt
    
    int data ;
    while( (data = is.read()) != -1) {
        ps.write(data);
    }
    is.close();  // 因为关联的文件,所以要关闭输入流和输出流
    ps.close();
    

    22.11_IO流(修改标准输入输出流拷贝图片)(了解)

    System.setIn(new FileInputStream("xxoo.jpg")); //改变标准输入流
    System.setOut(new PrintStream("copy.jpg"));  //改变标准输出流
    InputStream is = System.in;  
    PrintStream ps = System.out;  
    
    byte[] data = new byte[1024 * 10];
    int len;
    while( (len = is.read(data)) != -1) {
        ps.write(data, 0, len);
    }
    is.close();  
    ps.close();
    

    22.11_IO流(两种方式实现键盘录入)(了解)

    // 2种键盘录入
    // InputStreamReader转换流
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = br.readLine();
    br.close();
    System.out.println(str);
    
    Scanner sc = new Scanner(System.in);  // 第二种键盘输入
    String str2 = sc.nextLine();
    sc.close();
    System.out.println(str2);
    

    22.12_随机访问流概述和读写数据)(了解)

    • RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStreamOutputStream的功能。
    • 支持对随机访问文件的读取和写入。
    • 这个seek()跳字节读取的功能,可以用于多线程下载和上传。
    RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
    
    raf.write(97);  //写入 a
    
    int x = raf.read();  // 读取 (发现读取的不是97,说明指针移到了下一个字节)
    System.out.println(x);
    
    raf.seek(10);  //当当前指针遇到10的位置
    raf.write(120);
    
    raf.close();
    

    22.13_IO流(数据输入输出流)(了解)

    • DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
    • 例如按Long大小写出一个数字, 写出时该数据占8字节. 读取的时候也可以按照Long类型读取, 一次读取8个字节.
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
    dos.writeInt(997);  //写入真实的 997 ,
    dos.writeInt(998);
    dos.close();
    
    DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
    System.out.println(dis.readInt());  // 按照 int读取一个值
    System.out.println(dis.readInt());
    dis.close();
    
    // 因为write(int a) 虽然接收是int,但是实际是byte类型的转换,实际写入时,不会超过byte的取值范围
    // 00000000 00000000 00000011 11100101 int类型的997 
    // 11100101 真实写入的值, write写入会去掉int的前24位,而11100101找不到对应的码表,就会是乱码
    // 00000000 00000000 00000000 11100101 读取之后的int已经是 229了
    FileOutputStream fos = new FileOutputStream("a.txt");
    fos.write(997);   //结果发现写入之后是乱码的
    fos.close();
    

    22.14_Properties的概述和作为Map集合的使用(了解)

    • Properties 类表示了一个持久的属性集,本质是一个双列集合,因为键值都是字符串,所以没有泛型。
    • Properties 可保存在流中或从流中加载。
    • 属性列表中每个键及其对应值都是一个字符串。
    Properties pp = new Properties();
    pp.put("verson", "2.3.0");
    System.out.println(pp);
    

    22.15_Properties的特殊功能使用(了解)

    • Properties的特殊功能
    Properties pp = new Properties();
    pp.setProperty("verson", "3.2.0");  //向里面添加键值对
    pp.setProperty("type", "android");
    
    // 遍历 (强转是因为泛型问题)
    Enumeration<String> enu = (Enumeration<String>) pp.propertyNames();
    while(enu.hasMoreElements()){
            String key = enu.nextElement() ;
            System.out.println( key + "-->" + pp.get(key));  // 根据key,获取value
    }
    

    22.16_Properties的load()和store()功能(了解)

    Properties pp = new Properties();
    pp.load(new FileInputStream("config.list"));  //将文件上的键值对读取到集合中
    System.out.println(pp);
    
    // 修改配置
    pp.setProperty("name", "Java EE");
    // 写入配置文件
    pp.store(new FileOutputStream("config.list"), "我是描述信息,可以为null");
    

    END。
    我是小侯爷。
    在魔都艰苦奋斗,白天是上班族,晚上是知识服务工作者。
    如果读完觉得有收获的话,记得关注和点赞哦。
    非要打赏的话,我也是不会拒绝的。

    相关文章

      网友评论

          本文标题:day22-序列流/内存流/对象操作流/打印流/随机流

          本文链接:https://www.haomeiwen.com/subject/grsxwttx.html