zoukankan      html  css  js  c++  java
  • IO流个人总结

    l/O流

    1、IO流

    1.1、概念

    数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出output ,即流向内存是输入流,流出内存的输出流。

    Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

    1.2、分类

    根据数据的流向分为:输入流和输出流。

    输入流 :把数据从 其他设备 上读取到 内存 中的流。

    输出流 :把数据从 内存 中写出到 其他设备 上的流。

    根据数据的类型分为:字节流和字符流。

    字节流 :以字节为单位,读写数据的流。

    字符流 :以字符为单位,读写数据的流。

    2、字节流

    一切文件(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都是按一个一个的字节存储的,所以传输文件的时候也是如此。所以,字节流可以传输任意文件数据。在操作流的时候,要了解到无论使用什么样的流对象,底层传输的始终为二进制数据。

    2.1、字节输出流--OutputStream

    该类是一个抽象类;表示字节输出流的所有类的超类,将指定的字节信息写出到目的文件。

    类中定义了字节输出流的基本共性功能方法。

    2.2、FileOutputStream类

    OutputStream的子类,该类多用于将数据写出到文件

    2.2.1、构造方法

    1  public static void main(String[] args) {
    2          //创建流对象时需要一个路径,路径中存在文件则清空文件数据,不存在则创建一个文件,
    3          //根据流对象创建输出流对象
    4          File file=new File("lina.txt");
    5          OutputStream out=new FileOutputStream(file);
    6          //根据文件名称创建输出流对象
    7          OutputStream out2=new FileOutputStream("lina.txt");
    8  }
    2.2.2、写出字节数据

     1  public static void main(String[] args) throws Exception {
     2          //创建流对象时需要一个路径,路径中存在文件则清空文件数据,不存在则创建一个文件,
     3          //根据流对象创建输出流对象
     4          File file=new File("lina.txt");
     5          OutputStream out=new FileOutputStream(file);
     6          //写出单个字节
     7          out.write(97);//写出第一个第1个字节到文件
     8          out.write(98);//写出第一个第2个字节到文件
     9          out.write(99);//写出第一个第3个字节到文件
    10          //写出字节数组
    11          String str="123";
    12          byte[] bs=str.getBytes();
    13          out.write(bs);
    14          //写出指定长度的字节数组
    15          out.write(bs, 0, 3);
    16          out.close();
    17  }
    2.2.3、数据追加写出到文件

    换行:Windows系统里,换行符号是 。

     out.write("
    ".getBytes());

    2.3、字节输入流--InputStream

    该类是一个抽象类,表示字节输入流的所有类的超类;

    可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

    2.4、FileInputSteam类

    文件输入流,从文件中读取字节。

    2.4.1、构造方法

    2.4.2、读取字节的数据

     1  public static void main(String[] args) throws IOException {
     2          //读取文件中的内容--
     3          File file=new File("lina.txt");
     4          if(file.exists()){
     5              //根据文件的对象创建一个字节输入流;读取的文件必须存在才能读
     6              InputStream in=new FileInputStream(file);
     7              //按字节读取--读取的结果提升为int类型;如果读取的结果是-1,代表读取文件到了结尾
     8              int num1=in.read();//读取第1个字节
     9              int num2=in.read();//读取第2个字节
    10              int num3=in.read();//读取第3个字节            
    11              System.out.println(num1+"=="+num2+"=="+num3);
    12              //按字节数组读取
    13              int len=(int) file.length();
    14              byte[] bs=new byte[len];
    15              in.read(bs);    
    16              String s=new String(bs);
    17              System.out.println(s);
    18              //读取指定长度的字节数组
    19              in.read(bs, 0, 5);
    20              in.close();
    21          }else{
    22              System.out.println("要读取的文件不存在!");
    23          }
    24      }

    2.5、PS:所有流最后都要关闭

    2.6、练习:复制文件

     1  public class Test3 {
     2      public static void mycopy(String sourceFile,String muBiaoFile) throws IOException{
     3          //从硬盘读取文件到写入到内存中
     4          InputStream in=new FileInputStream(sourceFile);
     5          //从内存中写出到指定硬盘
     6          OutputStream out=new FileOutputStream(muBiaoFile);
     7          byte[] b=new byte[1024];
     8          while(in.read(b)!=-1){//==-1表示文件读取到了结尾
     9              out.write(b);
    10          }
    11          in.close();     
    12          out.close();
    13      }
    14      
    15      public static void main(String[] args) {
    16          try {
    17              mycopy("d:/Wildlife.wmv", "e:/Wildlife.wmv");
    18          } catch (IOException e) {
    19              e.printStackTrace();
    20          }
    21      }

    3、字符流

    当使用字节流读取文本文件时,当遇到遇到中文字符时,可能因为一个中文字符可能占用多个字节存储而出现问题。所以Java提供了字符流类,以字符为单位读写数据,专门用于处理文本文件。

    3.1、字符输入流--Reader

    java.io.Reader 是一个抽象类,该类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

    3.2、FileReader类

    阅读字符文件的便利类。 该类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。

    字节缓冲区:一个字节数组,用来临时存储字节数据。

    字符编码:字节与字符的对应规则。

    3.2.1、构造方法

    1  public static void main(String[] args) throws FileNotFoundException {
    2          //根据文件对象创建---字符输入流
    3          File file=new File("lina.txt");
    4          Reader reader=new FileReader(file);
    5          //根据文件名称创建---字符输入流
    6          Reader reader2=new FileReader("lina.txt");
    7      }
    8
    3.2.2、读入方法

     
     1 public static void main(String[] args) throws IOException {
     2          //根据文件对象创建---字符输入流
     3          File file=new File("lina.txt");
     4          Reader reader=new FileReader(file);
     5          //读取单个字符
     6          int num=reader.read();
     7          System.out.println(num);
     8          num=reader.read();
     9          System.out.println(num);
    10          num=reader.read();
    11          System.out.println(num);
    12          //读取字符数组
    13          char[] cs=new char[20];
    14          //read()返回值:读取到的真正的字符的个数
    15          int num2=reader.read(cs);
    16          System.out.println(num2);
    17          for (char c : cs) {
    18              System.out.println(c);
    19          }
    20          //读取指定长度的字符放入数组
    21          num2=reader.read(cs, 3, 10);
    22          reader.close();
    23      }

    3.3、字符输出流--Writer

    是一个抽象类,该抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字符输出流的基本共性功能方法。

    3.4、FileWriter类

    java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

    3.4.1、构造方法

    3.4.2、写出数据的方法
     1  public static void main(String[] args) throws IOException {
     2          File file=new File("lina.txt");
     3          //根据文件对象创建---字符输出流
     4          Writer w=new FileWriter(file);
     5          //写出数据
     6          //写出字符串
     7          w.write("中国");
     8          //写出字符的数组   
     9          char[] cs={'你','好','啊','a'};
    10          w.write(cs);
    11          //写入整数,不是写入的数字,写入的是整数对应的字符
    12          w.write(97);
    13          w.flush();//刷新缓冲区,强行将缓冲区中的无内容写出到文件中;刷新之后的流依然可用
    14          w.close();//先刷新缓冲,再关闭流,流不可用了
    15          System.out.println("over");
    16      }

    4、缓冲区

    在基本的流对象基础之上创建而来的,是对基本流对象的一种增强。

    4.1、概述

    缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,

    按照数据类型分类:

    字节缓冲流: BufferedInputStream , BufferedOutputStream

    字符缓冲流: BufferedReader , BufferedWriter

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

    4.2、字节缓冲流

    4.2.1、构造方法

     1  public static void main(String[] args) throws FileNotFoundException {
     2          File file=new File("lina.txt");
     3          //创建字节输入流
     4          InputStream in=new FileInputStream(file);
     5          //创建字节输出流
     6          OutputStream out=new FileOutputStream(file);
     7          //创建缓冲输入流
     8          BufferedInputStream bin=new BufferedInputStream(in);
     9          //创建缓冲输出流
    10          BufferedOutputStream bout=new BufferedOutputStream(out);    
    11      }
    4.2.2、高效体现
     1  public class Test5 {
     2      public static void mycopy(String sourceFile,String muBiaoFile) throws IOException{
     3          //从硬盘读取文件到写入到内存中
     4          InputStream in=new FileInputStream(sourceFile);
     5          //从内存中写出到指定硬盘
     6          OutputStream out=new FileOutputStream(muBiaoFile);
     7          byte[] b=new byte[100];
     8          long time1=System.currentTimeMillis();
     9          while(in.read(b)!=-1){//==-1表示文件读取到了结尾
    10              out.write(b);
    11          }
    12          long time2=System.currentTimeMillis();
    13          System.out.println(time2-time1+"----毫秒数");
    14          in.close(); 
    15          out.close();
    16      }
    17      
    18      public static void main(String[] args) {
    19          try {
    20              mycopy("d:/test.wmv","e:/test.wmv");
    21              mycopy2("d:/test.wmv","e:/test.wmv");
    22          } catch (IOException e) {
    23              e.printStackTrace();
    24          }
    25      }
    26      public static void mycopy2(String sourceFile,String muBiaoFile) throws IOException {
    27          File file=new File(sourceFile);
    28          File file2=new File(muBiaoFile);
    29          //创建字节输入流
    30          InputStream in=new FileInputStream(file);
    31          //创建字节输出流
    32          OutputStream out=new FileOutputStream(file2);
    33          //创建缓冲输入流
    34          BufferedInputStream bin=new BufferedInputStream(in);
    35          //创建缓冲输出流
    36          BufferedOutputStream bout=new BufferedOutputStream(out);
    37          //复制一个视频
    38          byte[] bs=new byte[100];
    39          long time1=System.currentTimeMillis();
    40          while(bin.read(bs)!=-1){
    41              bout.write(bs);
    42          }
    43          System.out.println("over");
    44          long time2=System.currentTimeMillis();
    45          System.out.println(time2-time1+"----毫秒数");
    46          bin.close();
    47          bout.close();
    48      }
    49  }

    4.3、字符缓冲流

    4.3.1、构造方法

    4.3.2、独有方法

    字符缓冲流的基本方法与普通字符流调用方式一致,不再列举。

    接下来说明字符缓冲流独有的方法:

    
    

    5、转换流

    5.1、字符编码和字符集

    计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制。

    数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照。

    某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。

    字符编码 Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则

    5.2、字符集

    字符集 Charset :也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

    计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有:ASCII字符集、GBK字符集、Unicode字符集等。

    当指定了编码,它所对应的字符集自然就指定了,所以编码很重要。

    下图是字符集与编码的对照。

    • ASCII字符集**

    ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。

    • ISO-8859-1*字符集:

    拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。ISO-5559-1使用单字节编码,兼容ASCII编码。

     

    • GBxxx字符集:

    GB就是国标的意思,是为了显示中文而设计的一套字符集。

    GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。

    GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。

    GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。

    • Unicode*字符集

    Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。

    UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:

    1. 128个US-ASCII字符,只需一个字节编码。

    2. 拉丁文等字符,需要二个字节编码。

    3. 大部分常用字(含中文),使用三个字节编码。

    4. 其他极少使用的Unicode辅助字符,使用四字节编码

    5.3、编码转换的问题

    不同编码格式会引发乱码问题,所以出现了转换流。转换流是字节与字符间的桥梁!

    5.4、InputStreamReader类

    转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

    5.4.1、构造方法

    InputStreamReader isr = new InputStreamReader(new FileInputStream("lina.txt"));

    InputStreamReader isr2 = new InputStreamReader(new FileInputStream("lina.txt") , "GBK");

    5.4.2、按照指定编码读取
     1 public class Ttest6 {
     2      public static void main(String[] args) throws IOException {
     3          InputStream in=new FileInputStream("lina.txt");//文件编码格式是UTF8
     4          InputStreamReader r1=new InputStreamReader(in,"GBK");
     5          char[] bs=new char[1024];
     6          while(r1.read(bs)!=-1){//使用GBK格式读取的结果会乱码
     7              System.out.println(new String(bs));
     8          }
     9          System.out.println("read over");
    10          r1.close();
    11      }
    12  }

    5.5、OutputStreamWriter类

    转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

    5.5.1、构造方法

     
    1 public static void write() throws IOException{
    2          OutputStream out=new FileOutputStream("lina.txt");
    3          OutputStreamWriter w=new OutputStreamWriter(out, "GBK");
    4          w.write("你好你好你好你好你好你好");
    5          w.close();
    6          System.out.println("write over");
    7  }
     1 public class Ttest6 {
     2      
     3      public static void read(String fileName,String charsetName) throws IOException{
     4          InputStream in=new FileInputStream(fileName);
     5          InputStreamReader r1=new InputStreamReader(in,charsetName);
     6          char[] bs=new char[1024];
     7          while(r1.read(bs)!=-1){//使用GBK格式读取的结果会乱码
     8              System.out.println(new String(bs));
     9          }
    10          System.out.println("read over");
    11          r1.close();
    12      }
    13      
    14      public static void write(String fileName,String charsetName) throws IOException{
    15          OutputStream out=new FileOutputStream(fileName);
    16          OutputStreamWriter w=new OutputStreamWriter(out, charsetName);
    17          w.write("你好你好你好你好你好你好");
    18          w.close();
    19          System.out.println("write over");
    20      }
    21      public static void main(String[] args) throws IOException {
    22          write("lina.txt","GBK");
    23          read("lina.txt","utf8");
    24      }
    25  }

    6、过滤流

    DataInputStream类:提供了往各种输入流对象中读取各种类型的数据的方法

    DataOutputStream类:提供了往各种输出流对象中写出各种类型的数据的方法

    6.1、构造方法

    1  InputStream in=new FileInputStream("lina.txt");
    2  OutputStream out=new FileOutputStream("lina.txt");
    3  DataInputStream din=new DataInputStream(in);
    4  DataOutputStream dout=new DataOutputStream(out);

    6.2、其他方法

    DataInputStream类中的读取数据的方法:

    DataOutputStream类的写出方法:

     1  public static void fun2() throws IOException {
     2          OutputStream out = new FileOutputStream("lina.txt");
     3          // 过滤流--封装了一些方法专门针对各种数据类的写入和写出
     4          DataOutputStream dout = new DataOutputStream(out);
     5          /*dout.writeUTF("utf你好!
    ");
     6          dout.write("你好!
    ".getBytes());*/
     7          dout.writeInt(100);
     8          dout.writeDouble(3.5);
     9          dout.writeBoolean(true);
    10          dout.close();
    11          System.out.println("write over");
    12          InputStream in = new FileInputStream("lina.txt");
    13          DataInputStream din = new DataInputStream(in);
    14          /*String s1 = din.readUTF();
    15          System.out.println(s1);
    16          byte[] bs = new byte[1024];
    17          while (din.read(bs) != -1) {
    18              System.out.print(new String(bs));
    19          }*/
    20          int num = din.readInt();
    21          double num2 = din.readDouble();
    22          boolean res = din.readBoolean();
    23          System.out.println(num);
    24          System.out.println(num2);
    25          System.out.println(res);
    26          System.out.println("read over");
    27          din.close();
    28      }

    7、序列化与反序列化

    7.1、概述

    Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的类型 和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象中存储的数据 信息,都可以用来在内存中创建对象。

    7.2、序列化

    把Java对象转换为字节序列的过程称为对象的序列化。

    7.3、序列化的条件

    一个对象要想序列化,必须满足两个条件:

    该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。

    该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬的,使用 transient 关键字修饰:为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

    1  public class Student implements Serializable{
    2      private String name;
    3      private Integer age;
    4      private Teacher teacher;
    5  }
    1  public class Teacher implements Serializable{
    2      private String name;
    3      private Integer age;
    4  }
     1  public static void main(String[] args) {
     2          Teacher t=new Teacher("lina", 20);
     3          Student s1 = new Student("baoyu", 16,t);
     4          try (OutputStream out = new FileOutputStream("lina.txt");
     5                  ObjectOutputStream o = new ObjectOutputStream(out);) {
     6              // 对象的序列化--将java对象从内存存储到硬盘
     7              o.writeObject(s1);
     8              System.out.println("over");
     9          } catch (Exception e) {
    10              e.printStackTrace();
    11          }
    12          try (
    13              InputStream in=new FileInputStream("lina.txt");
    14              ObjectInputStream i=new ObjectInputStream(in);
    15                  ){
    16              //对象的反序列化--从硬盘文件读取到内存中
    17              Object obj=i.readObject();
    18              if(obj!=null && obj instanceof Student){
    19                  Student s=(Student) obj;
    20                  System.out.println(s);
    21              }
    22          } catch (IOException | ClassNotFoundException e) {
    23              e.printStackTrace();
    24          }
    25      }

    8、Properties

    8.4、概述

    主要用于读取项目的配置文件,配置文件以.properties结尾的文件和xml文件。

    8.5、构造方法

    8.6、常用方法

     

  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/d-java/p/13232152.html
Copyright © 2011-2022 走看看