经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
IO流
来源:cnblogs  作者:搁浅Lee  时间:2020/7/20 0:04:38  对本文有异议

字节流(以字节为单位)

  • 当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
  • 数据源可以是文件,还可以是数据库,网络甚至是其他的程序
  • 输入流: InputStream 输出流:OutputStream

字节输入输出流

  • 文件输出流(FileOutputStream)

    • OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。

    • FileOutputStream 是OutputStream子类

    • 将数据从内存写入到硬盘

      import java.io.FileOutputStream;
      import java.io.IOException;
      
      public class FileOutputStream01 {
          public static void main(String[] args) throws IOException {
              //创建一个FileOutputStream对象,构造方法传入写入数据的文件
              FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt");
              //调用FileOutputStream对象中的方法write,将数据写入文件
              fos.write(2333);
              //释放资源,流的使用会占用资源,使用完要将内存清空,提高程序效率
              fos.close();
          }
      }
      
    • 文件中一次写入多个字节:
      write(byte[] b):如果写入的第一个字节是正数(0-127),显示时会查询ASCII表;如果写入的第一个字节是负数,那么第一个字节和第二个字节会组成中文显示,查询系统默认码表(GBK)
      write(byte[] b, int off, int len)int off:数组b开始的索引;int len:写入几个字节

    • 文件续写:使用FileOutputStream中两个参数的构造方法

      FileOutputStream(String name, boolean append):append是续写开关,当为true时继续在文件末尾追加写数据,当为false时创建新文件覆盖原文件

  • 文件输入流(FileInputStream)

    • InputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。

    • FileInputStream 是InputStream子类

    • 将数据从硬盘写入到内存

      import java.io.FileInputStream;
      import java.io.IOException;
      
      public class FileInputStream01 {
          public static void main(String[] args) throws IOException {
              //创建FileInputStream对象
              FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\b.txt");
              //调用read方法,读取文件中的一个字节并返回,读取到文件的末尾返回-1
              int read = 0;
              while ((read= fis.read()) != -1) {
                  System.out.println(read);
              }
              //释放资源
              fis.close();
          }
      }
      
    • 文件中一次读取多个字节:

      read(byte[] b): 从输入流读取一定数量的字节,并将其存储在缓冲区数组b中

  • 复制文件(一读一写)

    package InputStream;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class CopyFile {
        public static void main(String[] args) throws IOException {
            long start = System.currentTimeMillis();
            FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\copy.jpg");
            FileInputStream fis = new FileInputStream("D:\\1.jpg");
            //使用数组缓冲区读取多个字节写入多个字节
            byte[] bytes = new byte[1024];
            int read = 0;
            while ((read = fis.read(bytes)) != -1){
                fos.write(bytes, 0, read);
            }
    
            //释放资源,先关写入再关读取
            fos.close();
            fis.close();
            long end = System.currentTimeMillis();
            System.out.println("复制完成,用时:"+(end-start)+"ms");
        }
    }
    

字符流(以字符为单位)

  • 当使用字节流读取文本,遇到中文时可能不会显示完整字符,因为中文可能占用多个字节存储
  • Java提供的字符流专门用于字符的形式读取和写入数据,专门用于处理文本文件
  • Reader是字符输入流最顶层的父类,是一个抽象类
  • Writer是字符输出流最顶层的父类,是一个抽象类

字符输入输出流

  • 文件字符输入流(FileReader)

    • FileReader 是Reader子类

    • 将硬盘文件中的数据以字符的方式读取到内存中

      import java.io.FileReader;
      import java.io.IOException;
      
      public class FileReaderDemo {
          public static void main(String[] args) throws IOException {
              //创建FileReader对象,构造方法中绑定数据源
              FileReader fr = new FileReader("IOAndProperties\\src\\OutputStream\\b.txt");
      
              //int read():读取单个字符并返回
              //int read(char[] cbuf):一次读取多个字符,并将数组存储数组中
              char[] cbuf = new char[1024];
              int len = 0;
              while ((len = fr.read(cbuf)) != -1){
                  System.out.println(new String(cbuf, 0, len));
              }
              //释放资源
              fr.close();
          }
      }
      
  • 文件字符输出流(FileWriter)

    • FileWriter 是Writer子类

    • 将内存中的数据以字符的方式写入文件中

    • 需要将内存缓冲区中的数据刷新到文件中

      import java.io.FileWriter;
      import java.io.IOException;
      
      public class FileWriterDemo {
          public static void main(String[] args) throws IOException {
              //创建FileWriter对象,构造方法中绑定数据目的地
              FileWriter fw = new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt");
      
              //调用write方法把数据写入内存缓冲区(字符转换为字节的过程)
              //void write(int c):写入单个字符
              //void write(char[] cbuf, int off, int len):一次写入多个字符
              //void write(String str):写入字符串
              //void write(String str, int off, int len):写入字符串一部分
              char[] cbuf = {'你', '好', 'c', 'd'};
              String str = "阴阳师";
              fw.write(cbuf, 0, 3);
              fw.write(str, 0, 3);
              
              //使用FileWriter中的方法flush,把内存缓冲区中的数据刷新到文件中
              fw.flush();
              //释放资源(也会先把内存缓冲区中的数据刷新到文件中)
              fw.close();
          }
      }
      

      flush和close方法的区别:flush刷新缓冲区,流对象可以继续使用;close先刷新缓冲区,然后通知系统释放资源,流对象不可以再被使用了

    • 文件续写:使用FileWriter中两个参数的构造方法

      FileWriter(String name, boolean append):append是续写开关,当为true时继续在文件末尾追加写数据,当为false时创建新文件覆盖原文件

Properties集合

  • Properties集合是一个双列集合,key和value都默认是字符串

  • Properties类表示了一个持久属性集,Properties可保存在流中也可从流中加载

  • Properties集合中的store方法把集合中的临时数据持久化写入到硬盘中保存

    传入字节输入流则不能保存中文,传入字符输入流则可以保存中文

  • Properties集合中的load方法把硬盘中保存的文件(键值对)读取到集合中使用

    传入字节输入流则不能读取中文,传入字符输入流则可以读取中文

    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Properties;
    
    //使用properties中的store方法将临时数据写入硬盘中存储
    public class Properties01 {
        public static void main(String[] args) throws IOException {
            //创建properties集合对象添加数据
            Properties date = new Properties();
            //创建字节/字符输出流对象
            FileWriter fw = new FileWriter("IOAndProperties\\src\\properties\\pro.txt");
            //往集合中添加数据
            date.setProperty("追月神","打火");
            date.setProperty("八岐大蛇","输出大佬");
            date.setProperty("山兔","拉条");
            date.setProperty("日和坊","奶妈");
            //使用store方法往硬盘中存储数据,comments为注释,不能使用中文,一般用空字符串
            date.store(fw, "save date");
            fw.close();
        }
    }
    
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    
    //使用properties中的load方法读取硬盘中的键值对数据
    //存储键值对数据的文件中,键值默认连接符可以是=,空格
    //存储键值对数据的文件中,使用#进行注释,被注释的键值对将不被读取
    public class PropertiesLoad {
        public static void main(String[] args) throws IOException {
            //创建Properties集合对象
            Properties date = new Properties();
            //使用load方法读取保存键值对数据的文件
            date.load(new FileReader("IOAndProperties\\src\\properties\\pro.txt"));
            //遍历Properties集合
            Set<String> set = date.stringPropertyNames();//将读取的key存入Set集合中
            for (String key : set) {
                String value = date.getProperty(key);//根据key读取value
                System.out.println(key+" "+value);
            }
        }
    }
    

缓冲流

字节流和字符流的弊端,在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。为了解决以上弊端,采用缓冲流。 缓冲流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

  • 字节缓冲流:BufferedInputStreamBufferedOutputStream

  • 字符缓冲流:BufferedReaderBufferedWriter

  • 基本原理:创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,提高读写效率

字节缓冲流

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//字节缓冲输出流
public class BufferedOutputStream01 {
    public static void main(String[] args) throws IOException {
        //创建一个FileOutputStream对象,构造方法传入写入数据的文件
        FileOutputStream fos = new FileOutputStream("IOAndProperties\\src\\OutputStream\\a.txt");
        //创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象
        BufferedOutputStream buff = new BufferedOutputStream(fos);
        //使用BufferedOutputStream中的write方法,将数据写入内存缓冲区
        String str = "你好";
        buff.write(str.getBytes());
        //使用BufferedOutputStream中的flush方法将内部缓冲区的数据刷新到文件中
        buff.flush();
        //释放资源(会先调用flush,上一步可省)
        buff.close();
    }
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

//字节缓冲输入流
public class BufferedInputStream01 {
    public static void main(String[] args) throws IOException {
        //创建一个FileInputStream对象,构造方法传入写入数据的文件
        FileInputStream fis = new FileInputStream("IOAndProperties\\src\\OutputStream\\a.txt");
        //创建BufferedInputStream对象,构造方法中传递FileInputStream对象
        BufferedInputStream buff = new BufferedInputStream(fis);
        //使用BufferedOutputStream中的read方法,读取对象
        int len = 0;
        byte[] cbuf = new byte[1024];
        while ((len = buff.read(cbuf)) !=-1){
            System.out.println(new String(cbuf, 0, len));
        }
        //释放资源
        buff.close();
    }
}

字符缓冲流

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

//字符缓冲输出流
public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
        //调用write方法写入数据
        bw.write("阴阳师你好");
        //刷新缓冲区,释放资源
        bw.flush();
        bw.close();
    }
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

//字符缓冲输入流
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入流对象
        BufferedReader br = new BufferedReader(new FileReader("IOAndProperties\\src\\ReaderAndWriter\\c.txt"));
        //使用read或readline读取数据,readline每次只读取一行
        String str;
        while ((str = br.readLine()) != null){
            System.out.println(str);
        }
        //释放资源
        br.close();
    }
}

序列化和反序列化

  • 对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘。

  • 一个对象以流的形式写入文件进行保存,叫做序列化

  • 把文件保存的对象以流的形式读取出来,叫做反序列化

  • 该对象所对应的类,必须实现Serializable接口

    Serializable接口也叫标记型接口,要进行序列化和反序列化的类必须实现Serializable接口,给该类添加一个标记,当进行序列化和反序列化时,就会检测类上是否有这个标记。有标记就可以序列化和反序列化,没有就会抛出NotSerializableException异常

  • 被static(静态关键字)和transient(瞬态关键字)修饰的成员变量不能被序列化

import java.io.Serializable;

public class Person implements Serializable {
    //自定义一个序列版本号,
    // 添加新的属性时重新编译,可以直接反序列化,不会抛出异常
    //该序列号即为默认的序列号
    static final long serialVersionUID  = 2L;
    private String name;
    private int age;

    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 +
                '}';
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

//序列化
public class ObjectOutputStream01 {
    public static void main(String[] args) throws IOException {
        //创建ObjectOutputStream对象,构造方法中传递字节输出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
        //利用writeObject方法写入Person对象
        oos.writeObject(new Person("angel", 18));
        //释放资源
        oos.close();
    }
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

//反序列化
public class ObjectInputStream01 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建ObjectInputStream对象,构造方法传入字节输入流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IOAndProperties\\src\\ObjectStream\\person.txt"));
        //使用readObject方法读取保存对象的文件
        Object o = ois.readObject();
        //释放资源
        ois.close();
        System.out.println(o.toString());
    }
}

原文链接:http://www.cnblogs.com/geqianLee/p/13341926.html

 友情链接: NPS  问卷模板