IO流

 

IO

I/O输入/输出(Input/Output),分为IO设备和IO接口两个部分。

在POSIX兼容的系统上,例如Linux系统,I/O操作可以有多种方式,比如DIO(Direct I/O),AIO(Asynchronous,I/O 异步I/O),Memory-Mapped I/O(内存映设I/O)等,不同的I/O方式有不同的实现方式和性能,在不同的应用中可以按情况选择不同的I/O方式。

io流最顶级的父类:

image-20200508215418182

一切皆为字节。

1字节流

1.1、字节输出流OutputStream

  • 已知直接子类:

    ByteArrayOutputStreamFileOutputStreamFilterOutputStreamObjectOutputStreamOutputStreamPipedOutputStream


    public abstract class OutputStream
    extends Object
    implements Closeable, Flushable

    这个抽象类是表示字节输出流的所有类的超类。输出流接收输出字节并将其发送到某个接收器。

    需要定义OutputStream子类的应用OutputStream必须至少提供一个写入一个字节输出的方法。

    • voidclose() 关闭此输出流并释放与此流相关联的任何系统资源。
      void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
      void write(byte[] b)b.length字节从指定的字节数组写入此输出流。
      void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
      abstract void write(int b) 将指定的字节写入此输出流。

1.2、FileOutputStream文件字节输出流

  • public class FileOutputStream
    extends OutputStream

    文件字节输出流是用于将数据写入到输出流File或一个FileDescriptor

    FileOutputStream用于写入诸如图像数据的原始字节流。 对于写入字符流,请考虑使用FileWriter

作用:把内存中的数据写入到硬盘的文件中。

    • Constructor and Description
      FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。 (目的地是一个文件的路径)
      FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
      FileOutputStream(FileDescriptor fdObj) 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
      FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。 (目的地是一个文件)
      FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。
      • 构造方法的作用:

        1、创建一个FileOutputStream对象

        2、会根据构造方法中传递文件/文件路径,创建一个空的文件

        3、会把FileOutputStream对象指向创建好的文件

image-20200508222525567

    • Modifier and TypeMethod and Description
      void close() 关闭此文件输出流并释放与此流相关联的任何系统资源。
      protected void finalize() 清理与文件的连接,并确保当没有更多的引用此流时,将调用此文件输出流的 close方法。
      FileChannel getChannel() 返回与此文件输出流相关联的唯一的FileChannel对象。
      FileDescriptor getFD() 返回与此流相关联的文件描述符。
      void write(byte[] b)b.length个字节从指定的字节数组写入此文件输出流。
      void write(byte[] b, int off, int len)len字节从位于索引 off的指定字节数组写入此文件输出流。
      void write(int b) 将指定的字节写入此文件输出流。
  • 写入数据的原理(内存———>硬盘)

    java程序-->jvm(Java虚拟机)-->OS(操作系统)-->OS调用写数据方法-->把数据写入到文件中

  • 字节输出流的使用步骤:

    1、创建一个FileOutputStream对象,构造方法中传递写入数组的目的地

    2、调用FileOutputStream对象中的write方法,把数据写入到文件中

    3、释放资源

    image-20200508230802646

/**
* @program: intellij idea
* @description:
* 构造方法的作用:
* 1、创建一个FileOutputStream对象
* 2、会根据构造方法中传递文件/文件路径,创建一个空的文件
* 3、会把FileOutputStream对象指向创建好的文件
* 写入数据的原理(内存———>硬盘):
* * java程序-->jvm(Java虚拟机)-->OS(操作系统)-->OS调用写数据方法-->把数据写入到文件中
* * 字节输出流的使用步骤:
* * 1、创建一个FileOutputStream对象,构造方法中传递写入数组的目的地
* * 2、调用FileOutputStream对象中的write方法,把数据写入到文件中
* * 3、释放资源
* @author: lixy
* @create: 2020-05-08 22:18
**/
public class Demo01OutputStream {
  public static void main(String[] args) {
      FileOutputStream fos = null;
      try {
          fos = new FileOutputStream("F:\\intellij idea\\io\\src\\com\\lixy\\demo01\\a.txt");
          //fos.write(98);
//           fos.write(new byte[]{-28, -67, -96, -27, -91, -67});
//           fos.write(new byte[]{-68,-69,-70,75,-72,-68});

//           fos.write(new byte[]{65,66,67,68,69},1,4);

//           String str = "你好";//[-28, -67, -96, -27, -91, -67]
//           System.out.println(Arrays.toString(str.getBytes()));
//           fos.write(str.getBytes());
          if (fos != null){
              fos.close();
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

1.3、字节输入流InputStream

1.4、FileInputStream文件字节输入流

作用:把硬盘文件中的数据,读取到内存中使用

构造方法:

FileInputStream(File file) 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。

FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

参数:读取文件的数据源

File file:文件

String name:文件的路径

构造方法的作用:

1、会创建一个FileInputStream对象

2、会把FileInputStream对象指定构造方法中要读取的文件

image-20200509114043845

public class Demo02InputStream {
  public static void main(String[] args) {
      FileInputStream fis = null;
      try {
          fis = new FileInputStream("F:\\intellij idea\\io\\src\\com\\lixy\\demo01\\a.txt");
          /*int read = fis.read();
          System.out.println(read);
          int read2 = fis.read();
          System.out.println(read2);
          int read3 = fis.read();
          System.out.println(read3);
          int read4 = fis.read();
          System.out.println(read4);
          int read5 = fis.read();
          System.out.println(read5);*/
          int len = -1;
          while (true){
              len=fis.read();
              if (len != -1){
                  System.out.println(len);
              }else if (len == -1){
                  break;
              }
          }
      } catch (IOException e) {
          e.printStackTrace();
      }

  }
}

image-20200509123126279

public class Demo02InputStream {
  public static void main(String[] args) {
      FileInputStream fis = null;
      try {
        /*byte[] bytes = new byte[2];
          int len = fis.read(bytes);
          System.out.println(len);//2
          System.out.println(new String(bytes));//ab
          len = fis.read(bytes);
          System.out.println(len);//2
          System.out.println(new String(bytes));//cd
          len = fis.read(bytes);
          System.out.println(len);//1
          System.out.println(new String(bytes));//ed
          len = fis.read(bytes);
          System.out.println(len);//-1
          System.out.println(new String(bytes));//ed*/
           
          byte[] bytes = new byte[1024];
          int len = 0;
          while ((len = fis.read(bytes))!=-1){
                  System.out.println(new String(bytes,0,len));
          }
if (fis != null){
              fis.close();
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

image-20200509122922401

image-20200509165010687

文件的复制

public class Demo02Copy {
  public static void main(String[] args) {
      FileInputStream fis = null;
      FileOutputStream fos = null;
      try {
          fis = new FileInputStream("F:\\intellij idea\\io\\src\\com\\lixy\\demo01\\a.txt");
          fos = new FileOutputStream("F:\\intellij idea\\io\\src\\com\\lixy\\demo01\\liyi\\b.txt");
          byte[] bytes = new byte[1024];
          int len = 0;
          while ((len = fis.read(bytes)) != -1){
              System.out.println(len+"位,"+new String(bytes,0,len));
              fos.write(bytes,0,len);
          }
          if (fos != null){
              fos.close();
          }
          if (fis != null){
              fis.close();
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

image-20200509165534256

image-20200509165504972

2、字符流

2.1、字符输入流Reader

  • 已知直接子类:

    BufferedReaderCharArrayReaderFilterReaderInputStreamReaderPipedReaderStringReader


    public abstract class Reader
    extends Object
    implements Readable, Closeable

    用于读取字符流的抽象类。 子类必须实现的唯一方法是read(char [],int,int)和close()。然而,大多数子类将覆盖这里定义的一些方法,以便提供更高的效率,附加的功能或两者。

int read() 读一个字符

int read(char[] cbuf) 将字符读入数组。

void close()关闭流并释放与之相关联的任何系统资源。

2.2、FileReader文件字符输入流

作用:把硬盘文件中的数据以字符的方式读取到内存中

  • public class FileReader
    extends InputStreamReader

    阅读字符文件的便利类。该类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。要自己指定这些值,请在FileInputStream上构造一个InputStreamReader

    FileReader是用于读取字符流。 要读取原始字节流,请考虑使用FileInputStream

    FileReader构造方法:

  • FileReader(File file) 创建一个新的 FileReader ,给出 File读取。

  • FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。

    参数:

    File file 一个文件

    String fileName 文件的路径

    FileReader构造方法的作用:

    1、创建一个FileReader对象

    2、会把FileReader对象指向要读的文件

    字符输入流的使用步骤:

    1、创建FileReader对象,构造方法中绑定要读取的数据源

    2、使用FileReader对象中的read方法读取文件

    public class Demo02FileReader {
      public static void main(String[] args) {
          FileReader fr = null;
          try {
              fr = new FileReader("io\\a.txt");
              int len = 0;
              while ((len = fr.read())!= -1){
                  System.out.println((char)len);
              }
              if (fr != null){
                  fr.close();
              }
          } catch (IOException e) {
              e.printStackTrace();
          }

          /*FileReader fr = null;
          try {
              fr = new FileReader("io\\a.txt");
              char[] chars = new char[1024];//存储得到的多个字符
              int len = 0;//每次读取到的有效字符个数
              while ((len = fr.read(chars))!= -1){
                  System.out.println(len+"位,"+new String(chars,0,len));
              }
              if (fr != null){
                  fr.close();
              }
          } catch (IOException e) {
              e.printStackTrace();
          }*/
      }
    }

    2.3、字符输出流Writer

  • 已知直接子类:

    BufferedWriterCharArrayWriterFilterWriterOutputStreamWriterPipedWriterPrintWriterStringWriter


    public abstract class Writer
    extends Object
    implements Appendable, Closeable, Flushable

    用于写入字符流的抽象类。 子类必须实现的唯一方法是write(char [],int,int),flush()和close()。 然而,大多数子类将覆盖这里定义的一些方法,以便提供更高的效率,附加的功能或两者。

    • abstract voidclose() 关闭流,先刷新。
      abstract void flush() 刷新流。
      void write(char[] cbuf) 写入一个字符数组。
      abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
      void write(int c) 写一个字符
      void write(String str) 写一个字符串
      void write(String str, int off, int len) 写一个字符串的一部分。
  • 参数

    str - 要写入的字符串

    off - 从中开始读取字符的下标

    len - 要写入的字符数

2.4、FileWriter文件字符输出流

  • public class FileWriter
    extends OutputStreamWriter

    方便课写字符文件。该类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的。要自己指定这些值,请在FileOutputStream上构造一个OutputStreamWriter

作用:把内存中的字符写入到文件中

    • FileWriter(File file) 给一个File对象构造一个FileWriter对象。
      FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。
      FileWriter(FileDescriptor fd) 构造与文件描述符关联的FileWriter对象。
      FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。
      FileWriter(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。

File file:是一个文件;String fileName:文件的路径。

boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写;false:创建新的文件覆盖源文件

换行:换行符;windows:\r\n; linux:/r; mac:/r

构造方法的作用:

1、会创建一个filewriter 对象

2、会根据构造方法中传递的文件/文件路径,创建文件

3、会把filewriter对象指向创建好的文件

字符输出流的使用步骤:

1、创建FileWriter对象,构造方法中绑定要写入数据目的地

2、使用FileWriter中的write,把数据写入到内存缓冲区中(字符转换为字节的过程)

3、使用FileWriter的flush,把内存缓冲区中的数据,刷新到文件中

4、释放资源(会先把内存缓冲区中的数据刷新到文件中)

public class Demo03FileWriter {
  public static void main(String[] args) {
      FileWriter fw = null;
      try {
          fw = new FileWriter("io\\a.txt");
          /*char[] chars = "hah时间".toCharArray();
          fw.write(chars,3,2);*/

          fw.write("nihao世界",2,5);
          fw.flush();
          fw.close();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}
程序运行多次,文件内容:时间hao世界hahh22

关闭和刷新

flush:刷新缓冲区,流对象可以继续使用。

close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

public class Demo03FileWriter {
  public static void main(String[] args) {
      FileWriter fw = null;
      try {
          fw = new FileWriter("io\\c.txt",true);
          for (int i = 0; i < 2; i++) {
              fw.write("hello"+i+"\r\n");
          }
      } catch (IOException e) {
          e.printStackTrace();
      }finally {
          if (fw != null){
              try {
                  fw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  }
}
程序运行两次,文件内容:
hello0
hello1
hello0
hello1

jdk7新特性: try(){}catch{}

public class MyCopy {
  public static void main(String[] args) {
      try(FileWriter fw = new FileWriter("io\\D.txt",true);
          FileReader fr = new FileReader("io\\c.txt")){
          char[] chars = new char[1024];
          int len = 0;
          while ((len = fr.read(chars)) != -1){
              fw.write(chars,0,len);
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

3、Properties集合

  • public class Properties
    extends Hashtable<Object,Object>

    Properties类表示一组持久的属性。Properties可以保存到流中或从流中加载。属性列表中的每个键及其对应的值都是一个字符串。

    属性列表可以包含另一个属性列表作为其“默认值”; 如果在原始属性列表中找不到属性键,则会搜索此第二个属性列表。

image-20200510200256153

image-20200510200432785

image-20200510200622895

image-20200510203028188

public class MyProperties {
  public static void main(String[] args) {
      /*show01();
      show02();
      show03();*/
      Copy();
  }

  private static void Copy() {
      Properties properties = new Properties();
      Properties properties2 = new Properties();
      //读取
      try {
          properties.load(new FileReader("io\\c.txt"));
          Set<String> set = properties.stringPropertyNames();
          for (String s : set) {
              //set值
              properties2.setProperty(s,properties.getProperty(s));
          }
          //存储到文件里
          properties2.store(new FileWriter("io\\g.txt"),"gg");
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show03() {//读值
      Properties properties = new Properties();
      try {
          properties.load(new FileReader("io\\c.txt"));
          Set<String> set = properties.stringPropertyNames();
          for (String s : set) {
              System.out.println(s+"--"+properties.getProperty(s));
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show02() {//存储
      Properties properties = new Properties();
      properties.setProperty("aaa","111");
      properties.setProperty("里","222");
      properties.setProperty("ccc","333");

      FileWriter fw = null;
      try {
          fw = new FileWriter("io\\c.txt");
          properties.store(fw,"store");
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show01() {
      Properties properties = new Properties();
      properties.setProperty("aaa","111");
      properties.setProperty("里","222");
      properties.setProperty("ccc","333");
      Set<String> set = properties.stringPropertyNames();
      for (String s : set) {
          System.out.println(s + "--" + properties.getProperty(s));
      }
  }
}

4、缓冲流

4.1、BufferedOutputStream字节缓冲输出流

4.2、BufferedInputStream字节缓冲输入流

4.3、BufferedWriter字符缓冲输出流

4.4、BufferedReader字符缓冲输入流

image-20200510212200337

  • public class BufferedOutputStream
    extends FilterOutputStream

    该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。

    • Constructor and Description
      BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
      BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
    • Modifier and TypeMethod and Description
      void flush() 刷新缓冲输出流。
      void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。
      void write(int b) 将指定的字节写入缓冲的输出流。
public class MyBuffer {
  public static void main(String[] args) {
//       show01();//字节缓冲输出流
//       show02();//字节缓冲输入流
//       show03();//字符缓冲输出流
      show04();//字符缓冲输入流
  }

  private static void show04() {//字符缓冲输入流
      try (BufferedReader br = new BufferedReader(new FileReader("io\\c.txt"));){
          char[] chars = new char[1024];
          /*int len = 0;
          while ((len = br.read(chars)) != -1){
              System.out.println(new String(chars,0,len));
          }*/
          String s = null;
          while ((s = br.readLine()) != null){
              System.out.println(s);
          }

      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show03() {//字符缓冲输出流
      try(FileWriter fw = new FileWriter("io\\c.txt");
          BufferedWriter bw = new BufferedWriter(fw);) {
          bw.write("嘿嘿");
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show02() {//字节缓冲输入流
      try(FileInputStream fis = new FileInputStream("io\\c.txt");
          BufferedInputStream bis = new BufferedInputStream(fis);) {
          byte[] bytes = new byte[1024];
          int len = 0;
          while ((len = bis.read(bytes)) != -1){
              System.out.println(new String(bytes,0,len));
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

  private static void show01() {//字节缓冲输出流
      try(FileOutputStream fos = new FileOutputStream("io\\c.txt");
          BufferedOutputStream bos = new BufferedOutputStream(fos);) {
          bos.write("哈哈哈".getBytes());
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

5、转换流

image-20200510231444874

image-20200510231625101

image-20200510231912125

image-20200510232359571

5.1、InputStreamReader

  • 已知直接子类:

    FileReader


    public class InputStreamReader
    extends Reader

    InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。

    每个调用InputStreamReader的read()方法之一可能会导致从底层字节输入流读取一个或多个字节。 为了使字节有效地转换为字符,可以从底层流读取比满足当前读取操作所需的更多字节。

    • Constructor and Description
      InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
      InputStreamReader(InputStream in, Charset cs) 创建一个使用给定字符集的InputStreamReader。
      InputStreamReader(InputStream in, CharsetDecoder dec) 创建一个使用给定字符集解码器的InputStreamReader。
      InputStreamReader(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。

      参数:OutputStream out :字符输出流,可以用来写转换之后的字节到文件中

      String charsetName:指定的编码表名称,不区分大小写,可以是gbk/GBK,不指定默 认UTF-8

    • Modifier and TypeMethod and Description
      void close() 关闭流并释放与之相关联的任何系统资源。
      String getEncoding() 返回此流使用的字符编码的名称。
      int read() 读一个字符
      int read(char[] cbuf, int offset, int length) 将字符读入数组的一部分。
      boolean ready() 告诉这个流是否准备好被读取。

使用步骤:

1、创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称

2、使用InputStreamReader对象中的方法read,读取文件。

3、释放流

image-20200512201009914

public class demo01InputStreamReader {
  public static void main(String[] args) {
      read();
  }

  private static void read() {
      InputStreamReader isr =null;
      try {
          isr = new InputStreamReader(new FileInputStream("io\\c.txt"), "GBK");
          char[] chars = new char[1024];
          int len = 0;
          if ((len = isr.read(chars)) != -1){
              System.out.println(new String(chars,0,len));
          }
      } catch (IOException e) {
          e.printStackTrace();
      }finally {
          if (isr != null){
              try {
                  isr.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  }
}

5.2、OutputStreamWriter

  • 已知直接子类:

    FileWriter


    public class OutputStreamWriter
    extends Writer

    OutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset 。它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。

    每次调用write()方法都会使编码转换器在给定字符上被调用。 所得到的字节在写入底层输出流之前累积在缓冲区中。 可以指定此缓冲区的大小,但是默认情况下它大部分用于大多数目的。 请注意,传递给write()方法的字符不会缓冲。

    为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用。

    • Constructor and Description
      OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。
      OutputStreamWriter(OutputStream out, Charset cs) 创建一个使用给定字符集的OutputStreamWriter。
      OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建一个使用给定字符集编码器的OutputStreamWriter。
      OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。

      参数:OutputStream out :字符输出流,可以用来写转换之后的字节到文件中

String charsetName:指定的编码表名称,不区分大小写,可以是gbk/GBK,不指定默认UTF-8

    • Modifier and TypeMethod and Description
      void close() 关闭流,先刷新。
      void flush() 刷新流。
      String getEncoding() 返回此流使用的字符编码的名称。
      void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
      void write(int c) 写一个字符
      void write(String str, int off, int len) 写一个字符串的一部分。

使用步骤:

1、创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称

2、使用OutputStreamWriter对象中的方法write,把字符转换为字节存储在缓冲区中(编码)

3、使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)

4、释放流

public class demo01OutputStreamWriter {
  public static void main(String[] args) {
      writer();
  }
  private static void writer() {
      OutputStreamWriter osw = null;
      try {
          osw = new OutputStreamWriter(new FileOutputStream("io\\c.txt"), "GBK");
          osw.write("你好");
          osw.flush();
      } catch (IOException e) {
          e.printStackTrace();
      }finally {
          if (osw != null){
              try {
                  osw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }

  }
}

6、对象流

image-20200512210409315

6.1、ObjectOutputStream对象的序列化流

作用:把对象以流的方式写入到文件中保存

  • public class ObjectOutputStream
    extends OutputStream
    implements ObjectOutput, ObjectStreamConstants

    ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。

    只有支持java.io.Serializable接口的对象才能写入流中。 每个可序列化对象的类被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭。

    方法writeObject用于将一个对象写入流中。 任何对象,包括字符串和数组,都是用writeObject编写的。 多个对象或原语可以写入流。 必须从对应的ObjectInputstream读取对象,其类型和写入次序相同。

    • ModifierConstructor and Description
      protected ObjectOutputStream() 为完全重新实现ObjectOutputStream的子类提供一种方法,不必分配刚刚被ObjectOutputStream实现使用的私有数据。
        ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。

    参数:OutputStream out字节输出流

    void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。

使用步骤:

1、创建objectoutputstream对象,构造方法中传入字节输出流

2、使用objectoutputstream对象中的方法writeobject,把对象写入到文件中

3、释放资源

6.2、ObjectInputStream对象的反序列化流

  • public class ObjectInputStream
    extends InputStream
    implements ObjectInput, ObjectStreamConstants

    ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。

    ObjectOutputStream和ObjectInputStream可以分别为与FileOutputStream和FileInputStream一起使用的对象图提供持久性存储的应用程序。 ObjectInputStream用于恢复先前序列化的对象。 其他用途包括使用套接字流在主机之间传递对象,或者在远程通信系统中进行封送和解组参数和参数。

    ObjectInputStream确保从流中创建的图中的所有对象的类型与Java虚拟机中存在的类匹配。 根据需要使用标准机制加载类。

    只能从流中读取支持java.io.Serializable或java.io.Externalizable接口的对象。

    方法readObject用于从流中读取对象。 应使用Java的安全铸造来获得所需的类型。

    • ModifierConstructor and Description
      protected ObjectInputStream() 为完全重新实现ObjectInputStream的子类提供一种方法,不必分配刚刚被ObjectInputStream实现使用的私有数据。
        ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream。
public class Person implements Serializable {
  private String name;
  private Integer age;

  public Person() {
  }

  public Person(String name, Integer age) {
      this.name = name;
      this.age = age;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public Integer getAge() {
      return age;
  }

  public void setAge(Integer age) {
      this.age = age;
  }

  @Override
  public String toString() {
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              '}';
  }
}
public class Demo06Main {
  public static void main(String[] args) {
      Person person = new Person("李逸", 26);
      method(person);//把对象存入到文件中
      show();//把对象取出来
  }

  private static void show() {//反序列化流ObjectInputStream
      ObjectInputStream ois = null;
      try {
          ois = new ObjectInputStream(new FileInputStream("io\\h.txt"));
          Object o = ois.readObject();
          if (o != null){
              if (o instanceof Person){
                  System.out.println((Person)o);
              }
          }
      } catch (IOException e) {
          e.printStackTrace();
      }catch (ClassNotFoundException e) {
          e.printStackTrace();
      }finally {
          if (ois != null){
              try {
                  ois.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  }

  private static void method(Person person) {//序列化流ObjectOutputStream
      ObjectOutputStream oos = null;
      try {
          oos = new ObjectOutputStream(new FileOutputStream("io\\h.txt"));
          oos.writeObject(person);
      } catch (IOException e) {
          e.printStackTrace();
      }finally {
          if (oos != null){
              try {
                  oos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  }
}

 

posted @ 2020-05-13 11:37  半颗桃核  阅读(224)  评论(0编辑  收藏  举报