那些年,菜丸被面试官逼疯的IO流

那些年,菜丸被面试官逼疯的IO流

首先我们需要知道什么是流?

流就是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。它的特性是进行数据传输。

接下来我们看看IO流的分类:

  1. 按流向分类:输入流、输出流
  2. 按操作对象分类:字节流、字符流
  3. 按功能分类:节点流、处理流

前方高能,坐下来请慢慢地听我说!

一:字节流和字符流
字节流:InputStream 和OutputStream 是java中可以按照最小字节单位读取的流,即每次读写一个字节,字节流是直接连接到输入源的流。
字符流:是以字符为单位进行数据处理的IO流。本质其实就是基于字节流读取时,去查找指定的码表。

二:字节流与字符流之间的区别:

  1. 读写单位不同:字节流式以字节(8位2进制)为单位,字符流是以字符为单位,根据码表映射字符,一次可能读多个字节。
  2. 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
  3. 一次读入或读出是8位二进制。
  4. 字符流:一次读入或读出是16位二进制。

结论:

Out—>将输出的字符流—>字节流—>用于输出到控制台 或者 文件
注意这个是写====输出的是来源,形容词,不是你理解的字符输出流转字节输出流



In—>将输入的字节流—>字符流—>用于读取到控制台 或 内存
注意这个是读====输入的是来源,形容词,不是你理解的字节输入流转字符输入流

要么字节流要么字符流,具体再分哪种来源的流的话,就看是In还是Out了

  1. InputStreamReader看似是往里写(In),其实是往外读(Reader)
  2. OutputStreamWriter看似是往外读(Out),其实是往里写(Writer)

三:输入流和输出流的用途:

  1. 输入流是指程序从数据源中读取数据。只进行读操作;
  2. 输出流是指将数据从程序中写到指定的文件中;

四:输入流字节流InputStream与输出字节流InputStream

  1. InputStream是一个抽象类,是所有输入字节流的父类。
  2. ByteArrayInputStream、StringBufferInputStream、FileInputStream
    他们分别从数组、StringBuffer、和本地文件中读取数据。
  3. PipedInputStream是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
  4. ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。
  5. OutputStream 是所有的输出字节流的父类,它是一个抽象类。
  6. ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据。
  7. PipedOutputStream 是向与其它线程共用的管道中写入数据。
  8. ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。

上代码理解一下,此代码使用缓冲数组的方法读取文件内容,提高效率

public static void readArr() {
     // 1、明确源数据源
    File f = new File("F:/1/菜丸子/1.txt");
    // 2、构建流的对象
    InputStream ins = null;
     try {
         ins = new FileInputStream(f);
             // 3、声明缓冲数组
         int i;// 表示读取了多少个字符到数组中
          byte[] bt = new byte[5];// 字节缓冲数组
           // 4、读取数据到数组中
           //可以读多少写多少,转化成char类型,但是文件中都是英文,如果有中文则输出乱码
           while ((i = (ins.read(bt))) != -1) {
                  for (int j = 0; j < i; j++) {
                       System.out.print((char) bt[j]);
                     }
                 }
          } catch (Exception e) {
          e.printStackTrace();
          } finally {
           //关闭流
           try {
               if (ins != null) {
                 ins.close();
                  }
            } catch (Exception e) {
             e.printStackTrace();
         }
      }
 }

五:节点流和处理流的概念

节点流:直接与数据相连,进行数据的读写;

处理流:是指在节点流上套接了一层。

  • 常用的节点流
    1.文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件进行处理的节点流

import java.io.FileReader;
import java.io.FileWriter;
 /**
 *  使用FileRead、FileWriter复制文件
 *
 * @author  caiwan
 *
 */
public class TestFieldWriter {
public static void main(String []args){
  FileReader fr=null;
  FileWriter fw=null;
  try {
    fr=new FileReader("C:\\Users\\116060\\Desktop\\eeee.txt");//要读取的文件
    fw=new FileWriter("C:\\Users\\116060\\Desktop\\ffff.txt");//要复制的目的文件
    int i=0;
    while((i=fr.read())!=-1){
      fw.write(i);
      System.out.println((char)i);//将得到的ASCII码值转换成字符型
    }
    fr.close();
    fw.close();
  } catch (Exception e) {
    // TODO: handle exception
  }
}
}

2.数 组 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)

3.字符串 :StringReader、 StringWriter 对字符串进行处理的节点流

4.管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流

  • 常用的处理流

1.缓冲流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
/**
 * 字符缓冲流(使用 BufferedReader 和 BufferedWriter)
 *
 * @author  caiwan
 *
 */
public class Demo2 {
     public static void main(String[] args) {
           // 1、指明源和目标
           File o = new File("F:/temp/java11.template");
           File t = new File("F:/temp/java11.txt");
           // 2、构建流的对象
           Reader re = null;
           Writer wt = null;
           BufferedReader bfr = null;
           BufferedWriter bfw = null;
           try {
                re = new FileReader(o);
                bfr = new BufferedReader(re);
                wt = new FileWriter(t);
                bfw = new BufferedWriter(wt);
                String msg = null;
                // 读取操作
                while ((msg = bfr.readLine()) != null) {// 读一行
                     // System.out.println(msg);
                     bfw.write(msg);
                     bfw.write("\r\n");// 执行换行,读一行 写一行 换行
                     // 或者 :bfw.newLine();//换行
                }
                bfw.flush();
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                // 关闭流
                try {
                     if (wt != null) {// 为了避免空指针异常,进行判空
                           wt.close();
                     }
                     if (re != null) {
                           re.close();
                     }
                } catch (Exception e) {
                     e.printStackTrace();
                }
           }
     }
}

2.转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。

3.数据流: DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。

六:转换流

InputStreamReader 、OutputStreamWriter 要InputStream或OutputStream作为参数,实现从字节流到字符流的转换。

七:常用例子

包装流设置字符集的案例:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
/**
 * 包装流设置字符集,使用InputStreamReader 和 OUtputStreamWriter:
 * @author caiwan
 */
public class Demo01 {
     public static void main(String[] args) {
           // 确定源和目标文件
           Scanner sc = new Scanner(System.in);
           File o = new File("kh/java48.template");
           File t = new File("kh/java48.txt");
           check(o);
           check(t);
           // 构建流对象
           InputStream ins = null;
           OutputStream outs = null;
           InputStreamReader insr = null;
           OutputStreamWriter outsw = null;
           try {
                outs = new FileOutputStream(o);// 先做为目标文件写入内容
                outsw = new OutputStreamWriter(outs, "UTF-8");//编码格式为UTF-8
                System.out.println("输入你要写入的内容:");
                String msg = sc.next();
                // 写入内容
                outsw.write(msg);
                // 刷新
                outsw.flush();
                System.out.println("已经完全写入!");
                ins = new FileInputStream(o);// 作为源文件
                insr = new InputStreamReader(ins, "UTF-8");//编码格式为UTF-8
                outs = new FileOutputStream(t);// 作为写入的目标文件
                outsw = new OutputStreamWriter(outs, "UTF-8");//编码格式为UTF-8
                char[] ch = new char[1024];
                int i = 0;
                // 执行边读边写
                while ((i = insr.read(ch)) != -1) {
                     outsw.write(ch, 0, i);
                }
                // 刷新
                outsw.flush();
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                // 关闭流
                try {
                     if (outs != null) {
                           outs.close();
                     }
                     if (ins != null) {
                           ins.close();
                     }
                } catch (Exception e) {
                     e.printStackTrace();
                }
           }
     }
     public static void check(File file) {
           try {
                if (!file.exists()) {
                     file.getParentFile().mkdirs();// 创建文件夹
                     file.createNewFile();// 创建文件
                     System.out.println("没有该文件!已创建成功!");
                }
           } catch (Exception e) {
                e.printStackTrace();
           }
     }
}

最后:

欢迎各位小伙伴关注我的公众号:菜丸的程序屋。希望将我的不足之处给予指点,谢谢大家。喜欢Java,热衷学习的小伙伴可以加我微信: CaiWan_Y
在这里插入图片描述

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章