Java中的IO流

来源:互联网 发布:淘宝双11后生意不好 编辑:程序博客网 时间:2024/05/16 14:51

一、IO流的分类

  1. 流向
    输入流与 输出流

  2. 数据
    字节流:二进制(可以传输一切文件,包括纯文本,音频、视频等)
    字符流:文本文件,只能处理纯文本

  3. 功能
    节点流:包裹源头
    处理流:增强功能,提供性能

二、IO流基本步骤

  1. 创建源(文件/网络)

  2. 选择流

  3. 操作(读取/写出)

  4. 释放资源

三、流的种类

1. 节点流

(1) 字节流

1) 输入流(InputStream / FileInputStream / ByteArrayInputStream)

A. 操作:read(字节数组)        a) 中间容器            byte[] flush = new byte[长度];        b) 接收长度            int len = 0;        c) 循环读取            while( -1 != (len = 流.read(flush))){}        d) 操作            输出或者拷贝B. 重点方法        a) read(byte[] b)        b) read(byte[] b, int offset, int len)        c) close()

2) 输出流(OutputStream / FileOutputStream / ByteArrayInputStream)

A. 操作:write(字节数组, 0, 长度),输出B. 重点方法        a) write(byte[] b)        b) write(byte[] b, int off, int len)        c) flush();        d) close();

(2) 字符流

1) 输入流(Reader / FileReader)

A. 操作        //1、创建源        File src =new File("E:/xp/test/a.txt");        //2、选择流(FileReader)        Reader reader =null;        try {                reader =new FileReader(src);                //3、读取操作                char[] flush =new char[1024];                int len =0;                //循环读取                while(-1 != (len = reader.read(flush))){                //4、处理数据(字符数组转成 字符串)                String str =new String(flush,0,len);                System.out.println(str);              }        } catch (FileNotFoundException e) {               e.printStackTrace();               System.out.println("源文件不存在");        } catch (IOException e) {               e.printStackTrace();               System.out.println("文件读取失败");        }finally{               try {                       if (null != reader) {                       //5、关闭流                       reader.close();                       }                   } catch (Exception e2) {                   }        }B. 重点方法        a) read(char[] cbuf )        b) read(char[] cbuf, int off, int len)        c) close()

2) 输出流(Writer / FileWriter)

A. 操作        //1、创建源        File dest = new File("e:/xp/test/char.txt");        //2、选择流        Writer wr = null;        try {                //追加文件,而不是覆盖文件                wr = new FileWriter(dest);                //3、写出                String msg = "追加.....锄禾日当午\r\n码农真辛苦\r\n一本小破书\r\n一读一上午";                wr.write(msg);                wr.append("倒萨发了看电视剧 ");                wr.flush();        } catch (FileNotFoundException e) {                e.printStackTrace();        } catch (IOException e) {                e.printStackTrace();        } finally {                try {                        if (null != wr) {                        //4、关闭流                        wr.close();                        }                 } catch (Exception e2) {                 }        }B. 重点方法        a) write(char[] cbuf)        b) write(char[] cbuf, int off, int len)        c) flush()        d) close()

2. 处理流

处理流:增强功能、提供性能,节点流之上

(1) 缓冲流(BufferedInputStream / BufferedOutputStream , BufferedReader / BufferedWrite)

1) 字节缓冲流(BufferedInputStream / BufferedOutputStream)

2) 字符缓冲流(BufferedReader / BufferedWriter)

    a. 重点方法            a) readLine();            b) newLine();

3) 代码示例

    a. 字节流 + 缓冲流            //1、建立联系 源(存在且为文件) +目的地(文件可以不存在)            File src =new File(srcPath);            File dest =new File(destPath);            if(! src.isFile()){ //不是文件或者为null                System.out.println("只能拷贝文件");                throw new IOException("只能拷贝文件");            }            //2、选择流            InputStream is = new BufferedInputStream(new FileInputStream(src));            OutputStream os = new BufferedOutputStream( new FileOutputStream(dest));            //3、文件拷贝   循环+读取+写出            byte[] flush =new byte[1024];            int len =0;            //读取            try {                    while(-1!=(len=is.read(flush))){                    //写出                    os.write(flush, 0, len);                }             } catch (IOException e) {                    e.printStackTrace();             }             os.flush(); //强制刷出             //4、关闭流             os.close();             try {                     is.close();             } catch (IOException e) {                     e.printStackTrace();             }    b. 字符流 + 缓冲流             //1、创建源 仅限于 字符的纯文本             File src = new File("E:/xp/test/Demo03.java");             File dest = new File("e:/xp/test/char.txt");             //2、选择流             BufferedReader reader = null;             BufferedWriter wr = null;             try {                     reader = new BufferedReader(new FileReader(src));                     wr = new BufferedWriter(new FileWriter(dest));                     //3、读取操作                     /*                     char[] flush =new char[1024];                     int len =0;                     while(-1!=(len=reader.read(flush))){                         wr.write(flush, 0, len);                     }*/                     //新增方法的操作                     String line = null;                     while(null != (line = reader.readLine())){                         wr.write(line);                         //wr.append("\r\n");                         wr.newLine(); //换行符号                     }                     wr.flush();//强制刷出             } catch (FileNotFoundException e) {                     e.printStackTrace();                     System.out.println("源文件不存在");             } catch (IOException e) {                     e.printStackTrace();                     System.out.println("文件读取失败");             }finally{                     //4、关闭流                     try {                             if (null != wr) {                             wr.close();                         }                    } catch (Exception e2) {                    }                    try {                            if (null != reader) {                            reader.close();                    }                    } catch (Exception e2) {                    }             }

(2) 转换流(InputStreamReader / OutputStreamWriter)

功能:字节流转为字符流,处理乱码(编码集、解码集)
概念:

  • 编码:字符 —-编码字符集>>> 二进制
  • 解码:二进制 —-解码字符集>>> 字符
  • 乱码:编码和解码的字符集不统一,字节缺少,长度丢失

编码与解码代码示例

//指定解码字符集BufferedReader br =new BufferedReader(new InputStreamReader(                      //3).转换流              new BufferedInputStream(            //2).缓冲流              new FileInputStream(        //1).文件输入流              new File("E:/xp/test/Demo03.java"))),"UTF-8")            );//写出文件 编码BufferedWriter bw =new BufferedWriter(              new OutputStreamWriter(              new BufferedOutputStream(              new FileOutputStream(new File("E:/xp/test/encode.java")))));String info =null;while(null!=(info=br.readLine())){        //System.out.println(info);        bw.write(info);        bw.newLine();}//关闭流bw.flush();bw.close();br.close();

(3) 其他处理流

1) 基本类型处理流

a. 从文件流中读取
a) 输入流 DataInputStream readXxx()
    //创建源    File src =new File(destPath);    //选择流    DataInputStream dis =new DataInputStream(                  new BufferedInputStream(                  new FileInputStream(src)                  )    );    //操作 读取的顺序与写出一致   必须存在才能读取    //不一致,数据存在问题    long num2 =dis.readLong();    double num1 =dis.readDouble();    String str =dis.readUTF();    dis.close();    System.out.println(num2+"-->"+str);
b) 输出流 DataOutputStream writeXxx()
    double point =2.5;    long num=100L;    String str ="数据类型";    //创建源    File dest =new File(destPath);    //选择流  DataOutputStream    DataOutputStream dos =new DataOutputStream(                      new BufferedOutputStream(                      new FileOutputStream(dest)                      )                );    //操作 写出的顺序 为读取准备    dos.writeDouble(point);    dos.writeLong(num);    dos.writeUTF(str);    dos.flush();    //释放资源    dos.close();
b. 从字节流中读取
a) 输入流 DataInputStream
    //选择流    DataInputStream dis =new DataInputStream(                     new BufferedInputStream(                     new ByteArrayInputStream(src)                     )                  );    //操作 读取的顺序与写出一致   必须存在才能读取    double num1 =dis.readDouble();    long num2 =dis.readLong();    String str =dis.readUTF();    dis.close();    System.out.println(num1+"-->"+num2+"-->"+str);
b) 输出流 DataOutputStream
    //目标数组    byte[] dest =null;    double point =2.5;    long num=100L;    String str ="数据类型";    //选择流 ByteArrayOutputStream  DataOutputStream    ByteArrayOutputStream bos =new ByteArrayOutputStream();    DataOutputStream dos =new DataOutputStream(                       new BufferedOutputStream(                       bos                       )                   );    //操作 写出的顺序 为读取准备    dos.writeDouble(point);    dos.writeLong(num);    dos.writeUTF(str);          dos.flush();    //释放资源    dos.close();    //转换成字节数组    dest = bos.toByteArray();

2) 引用类型(对象)处理流

注意:

  • 先序列化后反序列化,反序列化顺序必须与序列化一致
  • 不是说是有的对象都可以序列化,必须继承 java.io.Serializable才可以
  • 不是所有的属性都需要序列化,用 transient 标注不需要序列化的变量

序列化的实体类代码示例

public class Employee implements java.io.Serializable {        //不需要序列化        private transient String name;        private double salary;        public Employee() {        }        public Employee(String name, double salary) {            super();            this.name = name;            this.salary = salary;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public double getSalary() {            return salary;        }        public void setSalary(double salary) {            this.salary = salary;        }}
a. 输入流(反序列化)
//创建源File src =new File(destPath);//选择流ObjectInputStream dis =new ObjectInputStream(                    new BufferedInputStream(                    new FileInputStream(src)                    )              );//操作 读取的顺序与写出一致   必须存在才能读取//不一致,数据存在问题Object obj = dis.readObject();if(obj instanceof Employee){    Employee emp = (Employee)obj;    System.out.println(emp.getName());    System.out.println(emp.getSalary());}obj = dis.readObject();int[] arr = (int[])obj;System.out.println(Arrays.toString(arr));dis.close();
b. 输出流(序列化)
Employee emp = new Employee("bjsxt",1000000);int[] arr ={1,2,3,45};//创建源File dest = new File(destPath);//选择流  ObjectOutputStreamObjectOutputStream dos = new ObjectOutputStream(                    new BufferedOutputStream(                    new FileOutputStream(dest)                    )               );//操作 写出的顺序 为读取准备dos.writeObject(emp);dos.writeObject(arr);//释放资源dos.close();

3) 打印流

a. 输入流
InputStream is = System.in;  //键盘输入//文件内容输入is = new BufferedInputStream(new FileInputStream("e:/xp/test/print.txt"));Scanner sc = new Scanner(is);//System.out.println("请输入:");System.out.println(sc.nextLine());
b. 输出流
a) 输出到文件
    System.out.println("test");    PrintStream ps =System.out;    ps.println(false);    //输出到文件    File src = new File("e:/xp/test/print.txt");    ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(src)));    ps.println("io is so easy....");    ps.close();
b) 切换输出流与控制台和文件流之间
    System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("e:/xp/test/print.txt")),true));    System.out.println("a");  //控制台  -->文件         System.out.println("test");    //回控制台    System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));    System.out.println("back....");

四、关闭流的工具类

public class FileUtil {    /**     * 工具类关闭流     * 可变参数: ...  只能形参最后一个位置,处理方式与数组一致     */    public static void close(Closeable ... io){        for(Closeable temp:io){            try {                if (null != temp) {                    temp.close();                }            } catch (Exception e) {            }        }    }    /**     * 使用泛型方法     */    public static <T extends Closeable> void closeAll(T ... io){        for(Closeable temp:io){            try {                if (null != temp) {                    temp.close();                }            } catch (Exception e) {            }        }    }}