首页 > 技术文章 > java02-IO流

ylrcblogs 2020-12-28 13:35 原文

io流的概念及分类

概念

  • io流是Input和Output的缩写,io流技术是非常实用的技术,用于处理设备之间的数据传输
  • java.io 包下提供了各种“流”的类和接口,以获取不同种类的数据,并通过标准的方法输入或输出;
  • 输入,输出,是一个相对的概念,这里所说的输入输出是站在程序的角度,也可以说是站在内存的角度;

流的分类

  • 按照数据的流向不同,分为:输入流,输出流;

  • 按照操作的数据单位的不同分为:字节流,字符流;

    • 字节流:常用在图片,音频等的输入输出,以一个字节一个字节的形式进行传输;
    • 字节流:常用在文本数据的输入输出,以两个字节(一个字符)的形式进行传输;
  • 按照角色的不同分为:节点流,处理流

    • 节点流:数据源或数据目的地直接连接;
    • 处理流:将节点流封装到处理流中,使节点流成为处理流的一个属性,通过添加一些其他的属性,增加流的特性;

io流的体系

抽象基类

抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

io流体系

分类 字节输入流 字节输出流 字符输入流 字节输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件(节点流) FileInputStream FileOutputStream FileReader FileWriter
访问数组(处理流) ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道(处理流) PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串(处理流) StringReader StringWriter
缓冲流(处理流) BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流(处理流) InputStreamReader InputStreamWriter
对象流(处理流) ObjectInputStream ObjectOutputStream
(处理流) FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流(处理流) PrintStream PrintWriter
推回输入流(处理流) PushbackInputStream PushbackReader
特殊流(处理流) DataStream DataOutputStream
  • File 开头的节点流,也可以叫做文件流;

  • Buffered 开头的是缓冲流

FileReader类

  • 在当前项目中创建 hello.txt ;

  • 创建测试类(方式一)

    public static void main(String[] args) {
            /*  知识点:
            *       1.流中的read()方法的理解:返回读取的一个字符int形式的值,若到达文件的末尾,则返回-1;
            *			read()方法每次读取一个字符;
            *       2.异常的处理,为了保证流资源一定要在执行完操作后关闭流;
            *       3.读入的文件一定要存在;
            * */
            // 1. 实例化File对象,指明要操作的文件,找好你的文件路径
            File file = new File("hello.txt");   //获取file的路径 file.getAbsolutePath()
            FileReader reader = null;
            try {
                // 2. 创建具体的流
                reader = new FileReader(file);
                int data ;
                // 3.用流中的read()方法读取数据;注:read()返回的是一个int值,若读取到数据的末尾,则返回-1
                while ((data = reader.read()) != -1){
                    System.out.print((char)data);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    //4.关闭流 注:若在第二步创建流时抛出异常(相当于流创建失败,实例化没有成功),则不需要关闭流,所以需要一个if
                    if (reader != null)
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    }
    
  • 方式二(优化方式一)

    @Test
    public void FileReaderTest02(){
        // 1.File实例化
        File file = new File("hello.txt");
        // 2.FileReader实例化
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            // 3.读写操作
    
            /*  (1)使用数组的形式,对数据进行读取,节省效率
           	 *  (2)流的read(char[] cbuf)方法,返回的是读取的字符的个数,若读取到数据的末尾,则返回-1
             * */
            //方式一
            /*char[] cbuf = new char[5];
            int len;
            while((len = reader.read(cbuf)) != -1){
                for (int i=0;i<len;i++){
                    System.out.print(cbuf[i]);
                }
            }
            System.out.println("---------------------");*/
            //方式二
            char[] cbuf1 = new char[5];
            int len1;
            while((len1 = reader.read(cbuf1)) != -1){
                String str = new String(cbuf1,0,len1);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 4.关闭流
            try {
                if (reader != null){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    FileWriter类

    直接上代码

    @Test
    public void FileWriterTest01()  {
        	/*  1.进行输入流操作的时候,不创建文件,不会报错,不会抛异常
            *   2.File对应的文件不存在: 输出过程中自动创建文件
            *   3.File对应的文件存在:
            *           若使用的构造器是new FileWriter(file,false) 或 new FileWriter(file) :会对原有文件进行覆盖
            *           若使用的构造器是new FileWriter(file,true):会在原有文件的基础上进行追加
            * */
    
        FileWriter writer = null;
        try {
            //1.实例化File
            File file = new File("hello01.txt");
            //2.实例化输出流FileWriter
            writer = new FileWriter(file);
            //3.将数据写出
            String str = "zihulongjing";
            writer.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭流
            if (writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    FileInputStream和FileOutputStream

    实现将图片复制

    @Test
    public void FileInputStreamTest(){
        /*  目的:将图片复制
        * */
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            // 1.实例化File(一个为存在的图片,一个为复制后的图片名)
            File fileI = new File("微信图片_20201221170613.jpg");
            File fileO = new File("微信图片.jpg");
    
            // 2.实例化流
            inputStream = new FileInputStream(fileI);
            outputStream = new FileOutputStream(fileO);
            // 3.读取和写出图片
            byte[] bytes = new byte[100];
            int len;
            while((len = inputStream.read(bytes)) != -1){
                outputStream.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            try {
                if(inputStream !=null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(outputStream !=null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

注意事项

  • 对文本文件(.txt ,.java ,.c ...)使用字符流处理
  • 对非文本文件(.jpg ,.mp3 ,.mp4 ,.doc ,.ppt ...),使用字节流处理

缓冲流

缓冲流

  • 缓冲对应四个节点流,在对应的节点流上进行封装

    FileInputStream ===> BufferedInputStreat

    FileOutputStream ===> BufferedOutputStreat

    FileReader ===> BufferedReader

    FileWriter ===> BufferedWriter

  • 作用:提高流的读写,写入的速度

  • 提高读写速度的原因:内部提供了一个缓冲区

BufferInputStream 和 BufferOutputStream 使用

@Test
public void BufferedStreat01(){
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        //1.造文件
        File file01 = new File("C:\\Users\\Administrator\\Desktop\\微信图片_20201221170613.jpg");
        File file02 = new File("C:\\Users\\Administrator\\Desktop\\微信图片.jpg");
        //2.造流
        FileInputStream inputStream = new FileInputStream(file01);
        FileOutputStream outputStream = new FileOutputStream(file02);

        //3.造缓冲流
        bufferedInputStream = new BufferedInputStream(inputStream);
        bufferedOutputStream = new BufferedOutputStream(outputStream);

        //4.读写数据
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(bytes)) != -1){
            bufferedOutputStream.write(bytes,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //5.关闭流
        /*  关闭流的注意事项:
        *       (1)在关闭流的时候,只需要关闭缓冲流就可以了,缓冲流封装的节点流在缓冲流的内部自行关闭
        * */
        if(bufferedInputStream != null){
            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bufferedOutputStream != null){
            try {
                bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedReader 和 BufferedWriter的使用

@Test
public void BufferStreamTest02(){
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        //1.造流
        bufferedReader = new BufferedReader(new FileReader("hello.txt"));
        bufferedWriter = new BufferedWriter(new FileWriter("hello02.txt"));

        //2.读写数据
        char[] buff =new char[1024];
        int len;
        while ((len = bufferedReader.read(buff)) != -1){
            bufferedWriter.write(buff,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭流
        if (bufferedReader != null){
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bufferedWriter != null){
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

推荐阅读