Java基础语法(二十三)

一.字节流

1.输入和输出
  • Output:把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作,程序到文件称为输出
  • Input:把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作,文件到程序称为输入
  • IO操作:把上面的这种输入和输出动作称为IO操作
2.字节输出流OutputStream
  • 字节输出流概念
    • IO流用来处理设备之间的数据传输
    • Java对数据的操作是通过流的方式
    • Java用于操作流的类都在IO包中
    • 流按流向分为两种:输入流,输出流。
    • 流按操作类型分为两种
    • 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
    • 字符流 : 字符流只能操作纯字符数据,比较方便。
  • IO流常用父类
    • 字节流的抽象父类:InputStream/OutputStream
    • 字符流的抽象父类:Reader/Writer
  • IO程序书写
    • 使用前:导入IO包中的类
    • 使用时:进行IO异常处理
    • 使用后:释放资源
  • 方法介绍
    • void close(): 关闭此输出流并释放与此流有关的所有系统资源。
    • void write(byte[] b): 将 b.length 个字节从指定的 byte 数组写入此输出流
    • void write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
    • abstract void write(int b) : 将指定的字节写入此输出流。
3.字节输出流FileOutputStream
  • FileOutputStream作用:写入数据文件,学习父类方法,使用子类对象

  • FileOutputStream构造方法:绑定输出目的

    • FileOutputStream(File file) :创建一个向指定 File 对象表示的文件中写入数据的文件输出流
    • FileOutputStream(File file, boolean append):创建一个向指定 File 对象表示的文件中写入数据的文件输出流,以追加的方式写入
    • FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流
    • FileOutputStream(String name, boolean append):创建一个向具有指定 name 的文件中写入数据的输出文件流,以追加的方式写入
  • 流对象使用步骤

    • 创建流子类的对象,绑定数据目的
    • 调用流对象的方法write写
    • close释放资源
  • 注意事项

    • 流对象的构造方法,可以创建文件,如果文件存在,直接覆盖
  • 实际代码

    /*
         *   FileOutputStream
         *   写入数据文件,学习父类方法,使用子类对象
         *   
         *   子类中的构造方法: 作用:绑定输出的输出目的
         *     参数:
         *       File    封装文件
         *       String  字符串的文件名
         *   
         *   流对象使用步骤
         *     1. 创建流子类的对象,绑定数据目的
         *     2. 调用流对象的方法write写
         *     3. close释放资源
         *     
         *    流对象的构造方法,可以创建文件,如果文件存在,直接覆盖
         */
    public class FileOutputStreamDemo {
      public static void main(String[] args)throws IOException {
          FileOutputStream fos = new FileOutputStream("c:\\a.txt");
          //流对象的方法write写数据
          //写1个字节
          fos.write(97);
          //关闭资源
          fos.close();
      }
    }
4.字节输出流FileOutputStream写入字节数组
  • FileOutputStream写入字节数组的方法

    • void write(byte[] b): 将 b.length 个字节从指定的 byte 数组写入此输出流
    • void write(byte[] b, int off, int len):将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
  • 实例代码

    /*
             *   FileOutputStream
             *   写入数据文件,学习父类方法,使用子类对象
             *   
             *   子类中的构造方法: 作用:绑定输出的输出目的
             *     参数:
             *       File    封装文件
             *       String  字符串的文件名
             *   
             *   流对象使用步骤
             *     1. 创建流子类的对象,绑定数据目的
             *     2. 调用流对象的方法write写
             *     3. close释放资源
             *     
             *    流对象的构造方法,可以创建文件,如果文件存在,直接覆盖
             */
    public class FileOutputStreamDemo {
      public static void main(String[] args)throws IOException {
          FileOutputStream fos = new FileOutputStream("c:\a.txt");
          //流对象的方法write写数据
          //写字节数组
          byte[] bytes = {65,66,67,68};
          fos.write(bytes);
          //写字节数组的一部分,开始索引,写几个
          fos.write(bytes, 1, 2);
          //写入字节数组的简便方式
          //写字符串
          fos.write("hello".getBytes());
          //关闭资源
          fos.close();
      }
    }
5.文件的续写和换行符号
  • 文件的续写:FileOutputStream构造方法, 的第二个参数中,加入true

  • 换行符号:

    • 在文件中,写入换行,符号换行 \r\n
    • \r\n 可以写在上一行的末尾, 也可以写在下一行的开头
  • 实例代码

    /*
                 *  FileOutputStream 文件的续写和换行问题
                 *  续写: FileOutputStream构造方法, 的第二个参数中,加入true
                 *  在文件中,写入换行,符号换行  \r\n
                 *  \r\n 可以写在上一行的末尾, 也可以写在下一行的开头
                 */
    
    public class FileOutputStreamDemo1 {
      public static void main(String[] args)throws IOException {
          File file = new File("c:\b.txt");
          FileOutputStream fos = new FileOutputStream(file,true);
          fos.write("hello\r\n".getBytes());
          fos.write("world".getBytes());
          fos.close();
      }
    }
6.IO中的异常处理
  • IO中的异常处理:try catch finally

  • 细节:

    • 保证流对象变量,作用域足够
    • catch里面,怎么处理异常
      • 输出异常的信息,目的看到哪里出现了问题
      • 停下程序,从新尝试
    • 如果流对象建立失败了,需要关闭资源吗
      • new 对象的时候,失败了,没有占用系统资源
      • 释放资源的时候,对流对象判断null
      • 变量不是null,对象建立成功,需要关闭资源
  • 实例代码

    public class FileOutputStreamDemo3 {
      public static void main(String[] args) {
          //try 外面声明变量,try 里面建立对象
          FileOutputStream fos = null;
          try{
              fos = new FileOutputStream("s:\\a.txt");
              fos.write(100);
          }catch(IOException ex){
              System.out.println(ex);
              throw new RuntimeException("文件写入失败,重试");
          }finally{
              try{
                  if(fos!=null)
                      fos.close();
              }catch(IOException ex){
                  throw new RuntimeException("关闭资源失败");
              }
          }
      }
    }
7.字节输入流InputStream
  • 方法介绍

    • abstract int read():从输入流中读取数据的下一个字节
    • int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,返回结果是读取到多少个有效的字节数;如果因为已经到达文件末尾而没有更多的数据,则返回 -1
    • int read(byte[] b, int off, int len):将输入流中最多 len 个数据字节读入 byte 数组
    • void close():关闭此输入流并释放与该流关联的所有系统资源
  • 字节输入流FileInputStream读取字节,实例代码

    public class FileInputStreamDemo {
      public static void main(String[] args) throws IOException {
          File file = new File("c:\\file.txt");
          //创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。
          FileInputStream fis = new FileInputStream(file);
          //读取数据。使用 read();一次读一个字节。
          int ch = 0;
          while((ch=fis.read())!=-1){
              System.out.println("ch="+(char)ch);
              // 关闭资源。
              fis.close();
          }
      }
    }
  • 字节输入流FileInputStream读取字节数组,实例代码

    /*
             *  FileInputStream读取文件
             *   读取方法  int read(byte[] b) 读取字节数组
             *   数组作用: 缓冲的作用, 提高效率
             *   read返回的int,表示什么含义 读取到多少个有效的字节数
             */
    public class FileInputStreamDemo1 {
      public static void main(String[] args) throws IOException {
          FileInputStream fis = new FileInputStream("c:\\a.txt");
          //创建字节数组
          byte[] b = new byte[1024];
    
          int len = 0 ;
          while( (len = fis.read(b)) !=-1){
              System.out.print(new String(b,0,len));//0表示b的开始索引,len表示读取个数
          }
          fis.close();
      }
    }
  • 字节输入流FileInputStream读取字节数组的实现原理

    这里写图片描述

8.文件复制

  • 实现原理

    这里写图片描述

  • 字节流复制文件读取单个字节,实例代码

    /*
             *  将数据源 c:\a.txt
             *  复制到 d:\a.txt  数据目的
             *  字节输入流,绑定数据源
             *  字节输出流,绑定数据目的
             *  
             *  输入,读取1个字节
             *  输出,写1个字节
             */
    public class Copy {
      public static void main(String[] args) {
          //定义两个流的对象变量
          FileInputStream fis = null;
          FileOutputStream fos = null;
          try{
              //建立两个流的对象,绑定数据源和数据目的
              fis = new FileInputStream("c:\t.zip");
              fos = new FileOutputStream("d:\t.zip");
              //字节输入流,读取1个字节,输出流写1个字节
              int len = 0 ;
              while((len = fis.read())!=-1){
                  fos.write(len);
              }
          }catch(IOException ex){
              System.out.println(ex);
              throw new RuntimeException("文件复制失败");
          }finally{
              try{
                  if(fos!=null)
                      fos.close();
              }catch(IOException ex){
                  throw new RuntimeException("释放资源失败");
              }finally{
                  try{
                      if(fis!=null)
                          fis.close();
                  }catch(IOException ex){
                      throw new RuntimeException("释放资源失败");
                  }
              }
          }
      }
    }
  • 字节流复制文件读取字节数组,实例代码

    /*
             *  字节流复制文件
             *   采用数组缓冲提高效率
             *   字节数组
             *   FileInputStream 读取字节数组
             *   FileOutputStream 写字节数组
             */
    public class Copy_1 {
      public static void main(String[] args) {
          long s = System.currentTimeMillis();
          FileInputStream fis = null;
          FileOutputStream fos = null;
          try{
              fis = new FileInputStream("c:\t.zip");
              fos = new FileOutputStream("d:\t.zip");
              //定义字节数组,缓冲
              byte[] bytes = new byte[1024*10];
              //读取数组,写入数组
              int len = 0 ; 
              while((len = fis.read(bytes))!=-1){
                  fos.write(bytes, 0, len);
              }
          }catch(IOException ex){
              System.out.println(ex);
              throw new RuntimeException("文件复制失败");
          }finally{
              try{
                  if(fos!=null)
                      fos.close();
              }catch(IOException ex){
                  throw new RuntimeException("释放资源失败");
              }finally{
                  try{
                      if(fis!=null)
                          fis.close();
                  }catch(IOException ex){
                      throw new RuntimeException("释放资源失败");
                  }
              }
          }
          long e = System.currentTimeMillis();
          System.out.println(e-s);
      }
    }
9.编码表
  • 定义:生活中字符和计算机二进制的对应关系表,就是编码表
  • 分类:
    • ascii:一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx
    • iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
    • GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数
    • GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0
    • unicode:国际标准码表:无论是什么文字,都用两个字节存储
    • Java中的char类型用的就是这个码表。char c = ‘a’;占两个字节
    • Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK
    • UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。
    • 能识别中文的码表:GBK、UTF-8;正因为识别中文码表不唯一,涉及到了编码解码问题
  • 编码和解码
    • 编码"abc".getBytes()
    • 解码new String(b)

二.字符流

1.字符输出流写文本FileWriter类
  • 方法介绍

    • void write(int c)写入单个字符
    • void write(String str)写入字符串
    • void write(String str, int off, int len)写入字符串的某一部分
    • void write(char[] cbuf)写入字符数组
    • abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分
  • 构造方法:File类型对象、String文件名

  • 注意事项:使用字符输出流写数据的时候,必须要运行刷新功能flush()

  • 实例代码

    /*
             *   字符输出流
             *     java.io.Writer 所有字符输出流的超类
             *   写文件,写文本文件
             *   
             *   写的方法 write
             *     write(int c) 写1个字符
             *     write(char[] c)写字符数组
             *     write(char[] c,int,int)字符数组一部分,开始索引,写几个
             *     write(String s) 写入字符串
             *     
             *   Writer类的子类对象 FileWriter
             *   
             *   构造方法:  写入的数据目的
             *     File 类型对象
             *     String 文件名
             *     
             *   字符输出流写数据的时候,必须要运行一个功能,刷新功能
             *   flush()
             */
    
    public class WriterDemo {
      public static void main(String[] args) throws IOException{
          FileWriter fw = new FileWriter("c:\1.txt");
          //写1个字符
          fw.write(100);
          fw.flush();
          //写1个字符数组
          char[] c = {'a','b','c','d','e'};
          fw.write(c);
          fw.flush();
          //写字符数组一部分
          fw.write(c, 2, 2);
          fw.flush();
          //写如字符串
          fw.write("hello");
          fw.flush();
          fw.close();
      }
    }
2.字符输入流读取文本FileReader类
  • 方法介绍

    • int read():读取单个字符
    • int read(char[] cbuf):将字符读入数组
    • abstract int read(char[] cbuf, int off, int len):将字符读入数组的某一部分
  • 实例代码

    public class ReaderDemo {
      public static void main(String[] args) throws IOException{
          FileReader fr = new FileReader("c:\1.txt");
          /*int len = 0 ;
                    while((len = fr.read())!=-1){
                        System.out.print((char)len);
                    }*/
          char[] ch = new char[1024];
          int len = 0 ;
          while((len = fr.read(ch))!=-1){
              System.out.print(new String(ch,0,len));
          }
          fr.close();
      }
    }
3.flush方法和close方法区别
  • flush方法:用来刷新缓冲区的,刷新后可以再次写出,只有字符流才需要刷新
  • close方法:用来关闭流释放资源的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出
4.字符流复制文本实例代码
/*
             *  字符流复制文本文件,必须文本文件
             *  字符流查询本机默认的编码表,简体中文GBK
             *  FileReader读取数据源
             *  FileWriter写入到数据目的
             */
public class Copy_2 {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try{
            fr = new FileReader("c:\1.txt");
            fw = new FileWriter("d:\1.txt");
            char[] cbuf = new char[1024];
            int len = 0 ;
            while(( len = fr.read(cbuf))!=-1){
                fw.write(cbuf, 0, len);
                fw.flush();
            }
        }catch(IOException ex){
            System.out.println(ex);
            throw new RuntimeException("复制失败");
        }finally{
            try{
                if(fw!=null)
                    fw.close();
            }catch(IOException ex){
                throw new RuntimeException("释放资源失败");
            }finally{
                try{
                    if(fr!=null)
                        fr.close();
                }catch(IOException ex){
                    throw new RuntimeException("释放资源失败");
                }
            }
        }
    }
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值