JavaSE进阶之(十二)I/O流

十二、I/O流

12.1 I/O概述

  • I/O的概述
    我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出 output ,即流向内存是输入流,流出内存的输出流。
    Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

  • I/O的分类

    • 根据数据的流向分为:输入流和输出流。
      输入流 :把数据从其他设备上读取到内存中的流。
      输出流 :把数据从内存中写出到其他设备上的流。
    • 格局数据的类型分为:字节流和字符流。
      字节流 :以字节为单位,读写数据的流。
      字符流 :以字符为单位,读写数据的流。
      在这里插入图片描述
  • I/O流向图解
    在这里插入图片描述

  • I/O顶级父类

    分类输入流输出流
    字节流字节输入流(InputStream)字节输出流(OutputStream)
    字符流字符输入流(Reader)字符输出流(Writer)

12.2 字节流

  • 字节输出流【OutputStream】
    java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字 节输出流的基本共性功能方法。

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

    java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。

    • 构造函数:
      1. public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
      2. public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
    public class FileOutputStreamConstructor throws IOException {     
    	public static void main(String[] args) {       
    		// 使用File对象创建流对象               
    		File file = new File("a.txt");         
    		FileOutputStream fos = new FileOutputStream(file);               
    
    		// 使用文件名称创建流对象         
    		FileOutputStream fos = new FileOutputStream("b.txt");     
    	} 
    }
    
    • 写出字节数据
    /**
    * 一.1.利用字节输出流向文件中写出数据
    */
    public void byteOutput(){
       File file = new File("F:\\代码\\后端\\JavaSE\\abc\\bbb.txt");
       try {
           //true表示追加内容,默认情况下后面内容覆盖前面内容
           OutputStream os = new FileOutputStream(file,true);
           /**
            * 1. 写出字节(String->Byte .getBytes())
            */
           os.write(97);
           //换行
           os.write("\r\n".getBytes());
           String content = "Hello World!";
           //默认全部写出
           os.write(content.getBytes());
           /**
            * 2. 写出字节数组
            */
           os.write("\r\n".getBytes());
           byte[] b = "河南科技大学".getBytes();
           os.write(b);
           /**
            * 3. 写出指定长度字节数组
            */
           //写出指定字符(注意:空格也算是一个字符!)
           os.write("\r\n".getBytes());
           os.write(content.getBytes(),2,5);
           os.write("\r\n".getBytes());
           os.write(b,1,5);
           os.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    
    • 数据追加续写
      这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。 这样创建的输出流对象,就可以指定是否追加续写了。
      public class byteOutputAppend {     
      	public static void main(String[] args) throws IOException {         
      		// 使用文件名称创建流对象         
      		FileOutputStream fos = new FileOutputStream("fos.txt"true);             
      		// 字符串转换为字节数组           
      		byte[] b = "abcde".getBytes();   
      		// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。                  
      		fos.write(b);        
      		// 关闭资源            
      		fos.close();     
      	} 
      } 
      
    • 写出换行

    回车符 \r 和换行符 \n :
    1. 回车符:回到一行的开头(return)。
    2. 换行符:下一行(newline)。

    系统中的换行:
    1. Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
    2. Unix系统里,每行结尾只有 换行 ,即 \n ;
    3. Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。

    小贴士:
    close方法,当完成流的操作时,必须调用此方法,释放系统资源。

  • ObjectOutputStream类:该流可以将一个对象写出,或者读取一个对象到程序中,也就是执行了序列化操作。

    /**
    * 一.2.使用对象操作流将对象写出到文件里(序列化)
    */
    public void objectOutputStream(){
       File file = new File("F:\\代码\\后端\\JavaSE\\abc\\fff.txt");
       try {
           OutputStream os = new FileOutputStream(file);
           Book book1 = new Book("1","红楼梦","曹雪芹",52);
           Book book2 = new Book("2","西游记","吴承恩",23);
           List<Book> blist = Arrays.asList(book1,book2);
           //序列化:讲对象写入到磁盘的过程,就是序列化
           ObjectOutputStream oos = new ObjectOutputStream(os);
           oos.writeObject(blist);
           oos.close();
           os.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    
  • 字节输入流【InputStream】
    java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入 流的基本共性功能方法。

    1. public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
    2. public abstract int read() : 从输入流读取数据的下一个字节。
    3. public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
  • FileInputStream类
    java.io.FileInputStream 类是文件输入流,从文件中读取字节。

    • 构造方法

      1. FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的File对象file命名。
      2. FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件 系统中的路径名name命名。
      public class FileInputStreamConstructor throws IOException{     
      	public static void main(String[] args) {       
      		// 使用File对象创建流对象               
      		File file = new File("a.txt");         
      		FileInputStream fos = new FileInputStream(file);                
      		// 使用文件名称创建流对象         
      		FileInputStream fos = new FileInputStream("b.txt");     
      	} 
      }
      
      • 读取字节数据
      /**
      * 利用字节输入流读取文件中的内容
      */
      public void byteInput() {
         File file = new File("F:\\代码\\后端\\JavaSE\\abc\\ccc.txt");
         try {
             InputStream is = new FileInputStream(file);
             /**
              * 1. 读取字节
              */
             //定义变量,保存数据
             int b;
             //循环读取
             while ((b = is.read()) != -1){
                 //b读取的是一堆数字码,强转后才能得到文件里的字符
                 System.out.print((char)b);
             }
             /**
              * 2. 使用字节数组读取(Byte->String new String())
              */
             //定义变量,作为有效个数
             int len;
             //定义字节数组,作为装字节数据的容器
             byte[] bb = new byte[2];
             //循环读取
             while ((len = is.read(bb)) != -1){
                 //每次读取后,把数组变成字符串打印
                 System.out.println(new String(bb,0,len));//每次读取有效的字节个数
             }
             is.close();
         } catch (Exception e) {
             e.printStackTrace();
         }
      }
      
  • ObjectInputStream类:ObjectInputStream能够让你从输入流中读取Java对象,而不需要每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了。

     /**
      * 二.2.读取文件中的数据(反序列化)
      */
    public void objectInputStream(){
        File file = new File("F:\\代码\\后端\\JavaSE\\abc\\fff.txt");
        try {
            InputStream is = new FileInputStream(file);
            //反序列化:将磁盘代码读取到代码中
            ObjectInputStream ois = new ObjectInputStream(is);
            Object object = ois.readObject();
            if (object != null){
                List<Book> blist = (List<Book>) object;
                for (Book b: blist){
                    System.out.println(b);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

12.3 字符流

Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文 件。

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

    1. public void close() :关闭此流并释放与此流相关联的任何系统资源。
    2. public int read() : 从输入流读取一个字符。
    3. public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
  • FileReader类
    java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

    • 构造方法
    1. FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
    2. FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
      当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。
      public class FileReaderConstructor throws IOException {     
      	public static void main(String[] args) {       
      		 // 使用File对象创建流对象               
      		 File file = new File("a.txt");        
      		  FileReader fr = new FileReader(file);               
      		 // 使用文件名称创建流对象         
      		 FileReader fr = new FileReader("b.txt"); 
      	} 
      }
      
    • 读取字符数据
      /**
      * 二.1.利用字符流读取文件中的数据
      */
      public void fileReader(){
         File file = new File("F:\\代码\\后端\\JavaSE\\abc\\ddd.txt");
         try {
             Reader reader = new FileReader(file);
             /**
              * 1. 读取字符
              */
             //定义变量,保存数据
             int b;
             while ((b = reader.read()) != -1){
                 System.out.println((char)b);
             }
             /**
              * 2. 使用字符数组读取
              */
             //定义变量,保存有效字符个数
             int len;
             //定义字符数组,作为装字符数据的容器
             char[] cb = new char[2];
             //循环读取
             while ((len = reader.read(cb)) != -1){
                 System.out.println(new String(cb));
             }
             reader.close();
         } catch (Exception e) {
             e.printStackTrace();
         }
      }
      
  • BufferedReader类:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

    /**
    * 二.2.使用字符缓冲流读取数据
    */
    public void bufferedReader(){
       File file = new File("F:\\代码\\后端\\JavaSE\\abc\\ddd.txt");
       try {
           Reader reader = new FileReader(file);
           //创建缓冲流
           BufferedReader bf = new BufferedReader(reader);
           String str = null;
           while ((str = bf.readLine()) != null){
               System.out.print(str);
           }
           bf.close();
           reader.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    
  • 字符输出流【Writer】
    java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节 输出流的基本共性功能方法。

    1. void write(int c) 写入单个字符。
    2. void write(char[] cbuf) 写入字符数组。
    3. abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len 写的字符个数。
    4. void write(String str) 写入字符串。
    5. void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个 数。
    6. void flush() 刷新该流的缓冲。
    7. void close() 关闭此流,但要先刷新它。
  • FileWriter类
    java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

    • 构造方法
    1. FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
    2. FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
      当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。
    public class FileWriterConstructor {     
    	public static void main(String[] args) throws IOException {       
    		// 使用File对象创建流对象               
    		File file = new File("a.txt");         
    		FileWriter fw = new FileWriter(file);                
    		// 使用文件名称创建流对象         
    		FileWriter fw = new FileWriter("b.txt");     
    	} 
    }
    
    • 写出数据
    /**
    * 一.1利用字符流向文件中写出数据
    */
    public void fileWriter(){
       File file = new File("F:\\代码\\后端\\JavaSE\\abc\\eee.txt");
       try {
           Writer writer = new FileWriter(file);
           /**
            * 1.写出字符
            */
           writer.write(97);
           writer.write('b');
           writer.write(30000);//田
           /**
            * 2. 写出字符数组
            */
           //字符串转换为字节数组
           char[] chars = "河南科技大学".toCharArray();
           //写出字符数组
           writer.write(chars);
           /**
            * 3. 写出字符串
            */
           String msg = "王老板";
           writer.write(msg);
           /**
            * 4. 续写和换行
            */
           //append设为true,表示可以续写
           Writer writer1 = new FileWriter(file,true);
           //写出字符串
           writer1.write("乔");
           //写出换行
           writer1.write("\r\n");
           writer1.write("老师");
           writer.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
    }
    

小贴士:
1.字符流,只能操作文本文件,不能操作图片,视频等非文本文件;
2.当我们单纯读或者写文本文件时使用字符流其他情况使用字节流。

  • BufferedWriter类:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

    /**
    * 一.2.使用字符缓冲流写出数据
    */
    public void bufferedWriter(){
       File file = new File("F:\\代码\\后端\\JavaSE\\abc\\fff.txt");
       try {
           Writer writer = new FileWriter(file);
           //创建缓冲流
           BufferedWriter bw = new BufferedWriter(writer);
           bw.write("中国人民站起来了!");
           bw.close();
           writer.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
    }
    

12.4 I/O异常

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值