zoukankan      html  css  js  c++  java
  • IO加强

    IO加强

    1字符流

    字符流只能读入文本,操作的是char,一个char等于二个bytes。

    字符流有二个父类

    1)重点为前二个子类
    

    Reader(字符输入流)分为以下子类

    *** BufferedReader*:基于缓冲区的读者**

    *** InputStreamReader在字节流和字符流之间做转换的流。*

    ​ 子类有一个FileReader,是一个基于磁盘文件的字符输入

    CharArrayReader:字符数组读者

    PipedReader:管道读者

    StringReader .. FilterReader ..

    Writer(字符输出流)分为一下子类:

    *** BufferedWriter***

    *** OutputStreamWriter***

    子类:FileWriter

    PrintWriter:打印写者并提供换行。

    CharArrayWriter

    PipedWriter

    FilterWriter .. StringWriter..

    字符流的作用:与字节流相比效率更高,因为一个字符=二个字节,但局限性,应用不广。
    

    1.1FileWriter

    是一个基于字符的文件输出流,用于在磁盘中对文本文件做写操作。

    构造方法和FileInputStream无大差别。

    FileWriter(String name)

    FileWriter(File file)

    FileWriter(String name,boolean append)

    FileWriter(File file,boolean append)

    下面这个成员方法:Writer(int c)指传入一个ASCII码,传入文件变为ASCII码对应的字符。

    场景:将字符写入磁盘

    package com.hujesse.IO;
    import java.io.FileWriter;
    public class FileWriterTest1 {
        public static void main(String[] args) {
            try(
                    FileWriter fw=new FileWriter("b.txt")
            ){
                char [] data = {'h','e','l','l','0'};
                // 将字符数组写入
                fw.write(data);
                //写入部分字符
                fw.writer(data,0,5);
                //写入单个字符
                fw.writer(100);
                //写入字符串
                fw.writer("Hujesse4");
                //写入部分字符串
                fw.writer("Hujesse4",0,5);
            }catch(Exception e){
                e.printStackTrace(); }
        }
    }
    

    1.2FileReader

    基于字符的文件输入流,用来读取磁盘文件的数据。

     // FileReader 的源码
     public FileReader(String fileName) throws FileNotFoundException {
            super(new FileInputStream(fileName));
        }
     // FileInputStream的源码
         public FileInputStream(String name) throws FileNotFoundException {
            this(name != null ? new File(name) : null);
        }
     //说明了字符流是基于字节流的
    

    场景:创建FileReader对象读取数据

    package com.hujesse.IO;
    import java.io.FileReader;
    import java.util.Arrays;
    public class FileWriterTest1 {
        public static void main(String[] args) {
            try(
                    FileReader fw=new FileReader("b.txt")
            ){
                // d定义一个字符数组,一次从磁盘读取多个
                char [] data = new char[32];
                fw.read(data);
                System.out.println(Arrays.toString(data));
            }catch(Exception e){
                e.printStackTrace(); } }}
    
    

    1.3文本文件的拷贝

    package com.hujesse.IO;
    import java.io.FileReader;
    import java.io.FileWriter;
    public class FileWriterTest1 {
        public static void main(String[] args) {
            try(
                    FileReader fr=new FileReader("b.txt");
                    FileWriter fw=new FileWriter("b_copy.txt");
            ){
                char []buffer = new char[32];
                int len;
                while ((len=fr.read(buffer))!=-1){
                    fw.write(buffer,0,len);
                }
            }catch(Exception e){
                e.printStackTrace(); } }}
    

    2缓冲流

    2.1相关概念

    流的分类

    流的流向:输入流和输出流

    按照数据类型:字节流和字符流

    按照功能:基础流和装饰流(处理流)

    什么是基础流:FileInputStream和FileOutputStream之间操作磁盘的。

    什么是装饰流:对基础流做了一个包装,例如FileReader对FileInputStream做了一个装饰,在创建FileReader同时创建了FileInputStream

    2.2带有缓冲区的装饰流(基于字节)

    带有缓冲区的好处(由来..whatever):内存读取数据快,磁盘读取数据慢,需要一个缓冲区来匹配速度

    基于字节的装饰流:

    BufferedInputStream & BufferedOutputStream

    2.2.1BufferedInputStream

    1)**BufferedInputStream 在基础流之上多了一个基于字节数组的缓冲区,默认大小为8192bytes。
    2)缓冲输入流相对于普通输入流的优势是,它提供了一个缓冲数组,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快。
    3) 里面有二个属性,pos(position)和count,当pos==count,说明读取完毕了
    

    场景:使用缓冲输入流读取磁盘数据并打印

    package com.hujesse.IO;
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    public class BufferedInputTest {
        public static void main(String[] args) {
            try(
                    BufferedInputStream bu = new BufferedInputStream(new FileInputStream("a.txt"));
                    ){
                //每次读取1024个字节
                byte[] data = new byte[1024];
                int len = 0;
                // 理解String StringBuffer StringBuilder的区别;capacity容积
                StringBuilder sb = new StringBuilder(500);
                while ((len=bu.read(data))!=-1){
                    //将字节数组转换为字符串
                    String str = new String(data,0,len);
                    //将字符串追加到StringBuilder
                    sb.append(str);
                }
                System.out.println(sb.toString());
            }catch (Exception e){
                e.printStackTrace(); } }}
    
    

    2.2.2BufferedOutputStream

    BufferedOutputStream是一个缓冲输出流,内部也有一个缓冲区,在写数据的时候,会将数据写入缓冲区直到写满,再讲缓冲区的数据一次性写入磁盘。

    场景:使用字节缓冲流拷贝图片
    package com.hujesse.IO;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    public class BufferedOutPutTest {
        public static void main(String[] args) {
            try (
                    BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("BufferCopy.jpg"));
                    BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\timg.jpg"));
            ) {
                byte[] data = new byte[1024];
                int len = 0;
                while ((len = in.read(data)) != -1) {
                    os.write(data, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } }}
    // 和FileInputStream操作真没什么区别
    

    唯一需要注意的是BufferOutputStream(OutputStream out)需要传入对象,子类也可以。

    2.3带有缓冲区的装饰流(基于字符)

    他们内部也有一个缓冲区,这个缓冲区是一个char[],默认长度为8192

    2.3.1BufferedReader

    构造方法:BufferedReader(Reader):创建一个基于字符的缓冲流,参数是一个Reader的子类,例如:FileReader。

    它除了支持read()的方法外还支持

    readLine():读取缓冲区里的一行数据,读到 就会结束。

    2.3.2 BufferedWriter

    构造方法:BufferWriter(Writer):创建一个基于字符的缓冲流,参数是一个Writer的子类,例如:FileWriter。

    还支持newLine():写入 换行

    场景:使用字符缓冲流进行文件的copy&paste
    package com.hujesse.IO;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    // bufferReader BUfferedWriter进行copy& paste
    public class BufferRead {
        public static void main(String[] args) {
            try(
                    BufferedReader bf = new BufferedReader(new FileReader("D:\bia.txt"));
                    BufferedWriter bw = new BufferedWriter(new FileWriter("copyChar.txt"));
                    ){
                // 用一个String类型接受数据
                        String line = null;
                        while ((line=bf.readLine())!=null){
                            bw.write(line);
                            //换行
                            bw.newLine();
                        }
            }catch (Exception e){
                e.printStackTrace(); } }}
    
    

    3内存流(重点)

    特征:数据的读和写都在内存中完成,可以将数据写入内存中,也可以从内存中读取数据。

    3.1 ByteArrayOutputStream

    基于字节的内存输出流,它是一个基础流,主要用于将程序中的数据转换为字节数组,然后写入流中。

    构造方法如下:

    ByteArrayOutputStream()无参构造方法,用来创建字节数组输出流对象。

    ByteArrayOutputStream(int size)同上,不过参数size是字节数组的长度。

    场景:定义一个变量,将其转换为字节数组,然后将其写入到ByteArrayOutputStream流里面

    package com.hujesse.IO;
    import java.io.ByteArrayOutputStream;
    public class ByteArrayOutStream {
        public static void main(String[] args) {
            try (
                    ByteArrayOutputStream bo = new ByteArrayOutputStream();
                    ) {
                String str = "helloIO";
                bo.write(str.getBytes());
                //bo.flush(); JVM自动帮我门做了这种事
            } catch (Exception e) {
                e.printStackTrace(); } }}
    

    3.2 ByteArrayInputStream

    是一个字节数组输入流,也是一个基础流,主要用于将内存的数据读取到程序中。

    场景:定义一个变量,将其转换为字节数组,然后将其写入到ByteArrayInputStream流,最后调取类的方法读取数据

    package com.hujesse.IO;
    import java.io.ByteArrayInputStream;
    public class ArrayInputStreamTest {
        public static void main(String[] args) {
            try(
                    ByteArrayInputStream bi = new ByteArrayInputStream("test".getBytes());
                    ){
                        int data = bi.read();
                    System.out.println((char)data);
            }catch(Exception e){
                e.printStackTrace();
            } }}
    // FileInputStream(String name)读取磁盘里面的数据
    //ByteArrayInputStream(byte[])读取内存中的数据
    
    综合案例:将百度服务器的logo下载到本地磁盘

    package com.hujesse.IO;
    /**
     * 场景:从百度服务器下载资源
     * 创建URL对象,指定百度服务器的地址
     * 打开URL链接
     * 读取百度服务器数据,将读取的数据存储到内存流
     * 创建FileInputStream,将内存流数据写到本地磁盘
     */
    import java.io.*;
    import java.net.URL;
    public class ArrayInputStreamTest {
        public static void main(String[] args) throws Exception{
            URL url = new URL("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png");
            try(
                    //url.openStream()相当于在浏览器输入服务器地址,然后回车
                    InputStream in = url.openStream();
                    ByteArrayOutputStream bo = new ByteArrayOutputStream();
                    ){
                // 使用输入流读取百度服务器图片,将读取的数据放进内存流
                        byte[] bufffer = new byte[1024];
                        int len = 0;
                        while ((len=in.read(bufffer))!=-1){
                            bo.write(bufffer,0,len); }
                        bo.flush();
                        // 获取内存流里面的字节数
                        try(
                                FileOutputStream fo = new FileOutputStream(new File("Logo.png"));
                                ){
                            //bo.toByteArray()将内存流里面的数据转换为字节数组
                            byte [] data2 = bo.toByteArray();
                            fo.write(data2);
                        }catch(Exception e
                        ){
                            e.printStackTrace();
                        }
            }catch (Exception e){
                e.printStackTrace(); } }}
    //最主要的是内存流有个方法 byteArrayOutputStream.toByteArray()
    //可以将内存流里面的的数据全部转换为字节数组
    

    4对象输入和输出流

    4.1 ObjectInputStream

    是一个基于字节的对象输入流,同时也是一个装饰流,主要用于读取内存中的对象

    构造方法:ObjectInputStream(InputStream)

    1)工作中可以使用对象输入和输出流来完成对象的克隆
    2)什么叫对象的克隆?在原始对象的基础上繁殖新对象,新对象数据和原对象一模一样
    

    4.2 ObjectOutputStream

    是一个基于字节的对象输出流,同时也是一个装饰流,主要用于读取内存中的对象

    构造方法:ObjectOutputStream(outputStream)

    场景:对象的克隆

    package com.hujesse.IO;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    public class ObjectInPutStreamCLONE {
        public static void main(String[] args) {
            Student hujesse4 = new Student(20, "hujesse4");
            try (
                    //创建原始输出流对象,将字节数组输出流注入到对象输出流里面
                    ByteArrayOutputStream bo= new ByteArrayOutputStream();
                    ObjectOutputStream op = new ObjectOutputStream(bo);
            ) {
                //将对象写入内存
                op.writeObject(hujesse4);
                try(
                        // 注意把输出流的内容转换为对象数组传给输入流.bo.toByteArray()存储了原始数据
                        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
                        ObjectInputStream ob = new ObjectInputStream(bi);
                        ){
                       Object stuClone = ob.readObject();
                    System.out.println(stuClone);
                }catch (Exception e){
                    System.out.println("clone Object failed");
                    e.printStackTrace();
                }
            } catch (Exception e) {
                System.out.println("clone Object failed");
                e.printStackTrace(); } }}
    
    
    package com.hujesse.IO;
    import java.io.Serializable;
    //参与clone的对象必须继承implements Serializable接口,否则抛出异常
    public class Student implements Serializable {
        private int age;
        private String name;
        /* getters and setters */
    

    小改进,写成一个静态方法

        public static Object ObejctClone (Object obj)throws Exception{
            try (
                    ByteArrayOutputStream bo = new ByteArrayOutputStream();
                    ObjectOutputStream oo = new ObjectOutputStream(bo);
                    ) {
                oo.writeObject(obj);
                try (
                        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
                        ObjectInputStream oi = new ObjectInputStream(bi);
                ){
                    return oi.readObject();
                } } }
    

    5转换流

    5.1 InputStreamReader

    它是一个连接字节流和字符流之间的桥梁,也是一个输入流

    // 为什么需要转换流 ---

    为了解决设备之间编码方式不统一的问题

    场景:将D盘目录下的一个文本文件拷贝,可它使用的是GBK编码,但IDEA使用的是UTF-8编码,拷贝会出现乱码。

    什么时候用呢:即源头编码和目标编码不一致时,使用转换流(指定编码格式)即解决乱码

    但是工作中一般定义有缓冲区的转换流

    new BufferedReader(new InputStreamReader(new FileInputStream("D:\bia.txt"),"GBK"))
    new BufferedWriter(new InputStreamWriter(new FileOutputStream("copy.txt"),"GBK"))
    

    场景:使用带有缓冲区的读者写者配合转换流进行文件的复制粘贴

    package com.hujesse.IO;
    import java.io.*;
    public class InputStreamReaderTES {
        public static void main(String[] args) {
         try(
                 BufferedReader bf=new BufferedReader(new InputStreamReader(new FileInputStream("D:\bia.txt"),"UTF-8"));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copy.txt"),"UTF-8"));
                 ){
             String line = null;
             while((line=bf.readLine())!=null){
                 bw.write(line);
                 bw.newLine();
             }
         }catch(Exception e){
             e.printStackTrace(); } }}
    
    

    5.2 OutputStreamWriter

    它是一个连接字节流和字符流之间的桥梁,也是一个输出流

    见上个场景

    6读写基本数据类型

    6.1 DataInputStream

    构造函数DataInputStream(InputStream )

    还提供了一些读写的方法

    readint()读整数

    readFloat()读单精度浮点小数

    readDouble()读双精度浮点小数

    readBoolean()读取Boolean

    readChar()读字符

    readUTF()读字符串

    6.2 DataOutputStream

    构造函数DataOutputStream(OutputStream)

    还提供了一些写的方法

    writeInt(int);写入整数

    writeFloat(Float):写入单精度浮点数



    场景:定义一个Student数组,使用DataOutputStream将数据写入磁盘,然后用DataInoutStream读写出来并打印;

    package com.hujesse.IO;
    import java.io.*;
    public class DataInOutputStreamTest {
        private static Student[] students = {
                new Student(20,"hujesse"),
                new Student(13,"cousin")};
        public static void main(String[] args)
        {
            try(
                DataOutputStream dot = new DataOutputStream(new FileOutputStream(new File("student")))
            ){
                for(Student stu:students){
                    dot.writeInt(stu.getAge());
                    dot.writeUTF(stu.getName());
                }
              try(
                      DataInputStream dit = new DataInputStream(new FileInputStream("student"));
                      ){
                  for(int i =0;i<students.length;i++){
                      int age = dit.readInt();
                      String name = dit.readUTF();
                      System.out.println(age);
                      System.out.println(name);
                  }
              }catch (Exception e){e.printStackTrace();
              }
            }catch (Exception e){e.printStackTrace();
            } }}
    
    

    7打印流(了解)

    PrintWriter:就是BufferedWriter + 换行

    PrintWriter时一个字符流同时也是一个装饰流提供了换行的功能;

    方法为:pw.println(args);

    小知识

    1)boolean不是布尔类型,而是logic(逻辑)类型
    
  • 相关阅读:
    指针详解(C语言)
    JMeter接口测试示例(六)——上传文件
    JMeter接口测试示例(五)——添加Cookie
    JMeter接口测试示例(四)——添加HTTP信息头
    JMeter接口测试参数化(函数生成器)
    JMeter接口测试——参数化
    Bootstrap简介
    jQuery文档节点处理,克隆,each循环,动画效果,插件
    什么是 jQuery 和jQuery的基本选择器,层级选择器,基本筛选器
    BOM对象,math对象document对象的属性和操作和 事件的基本操作
  • 原文地址:https://www.cnblogs.com/hujesse4/p/14304613.html
Copyright © 2011-2022 走看看