IO流概述与文件流的使用

1. IO流的分类
> 流向的不同:输入流、输出流
> 处理单位的不同:字节流、字符流
> 流的角色的不同:节点流、处理流

2. 基础IO流的框架:
抽象基类              4个节点流 (也称为文件流)
InputStream         FileInputStream
OutputStream        FileOutputStream
Reader              FileReader
Writer              FileWriter

说明:本章虽然涉及到的流很多,但是使用流进行数据的读写操作是非常标准和规范的。

3. FileReader \ FileWriter 的使用
3.1 执行步骤:
第1步:创建读取或写出的File类的对象
第2步:创建输入流或输出流
第3步:具体的读入或写出的过程。
     读入:read(char[] cbuffer)
     写出:write(String str) / write(char[] cbuffer,0,len)
第4步:关闭流资源,避免内存泄漏


3.2 注意点:
① 因为涉及到流资源的关闭操作,所以出现异常的话,需要使用try-catch-finally的方式来处理异常
② 对于输入流来讲,要求File类的对象对应的物理磁盘上的文件必须存在。否则,会报FileNotFoundException
   对于输出流来讲,File类的对象对应的物理磁盘上的文件可以不存在。
        > 如果此文件不存在,则在输出的过程中,会自动创建此文件,并写出数据到此文件中。
        > 如果此文件存在,使用 FileWriter(File file) 或 FileWriter(File file,false):
                                                输出数据过程中,会新建同名的文件对现有的文件进行覆盖。
                       FileWriter(File file,true) : 输出数据过程中,会在现有的文件的末尾追加写出内容。


4. FileInputStream \ FileOutputStream 的使用
4.1 执行步骤:
第1步:创建读取或写出的File类的对象
第2步:创建输入流或输出流
第3步:具体的读入或写出的过程。
     读入:read(byte[] buffer)
     写出:write(byte[] buffer,0,len)
第4步:关闭流资源,避免内存泄漏


4.2 注意点:
> 在3.2 注意点的基础之上,看其他的注意点。
> 对于字符流,只能用来操作文本文件,不能用来处理非文本文件的。
  对于字节流,通常是用来处理非文本文件的。但是,如果涉及到文本文件的复制操作,也可以使用字节流。


说明:
文本文件:.txt 、.java 、.c、.cpp、.py等
非文本文件:.doc、.xls 、.jpg 、.pdf、.mp3、.mp4、.avi 等



查看FileReader的API

FileReader是间接继承于Reader

所以可以用Reader的方法

int read() :每次读取一个字符  返回是Int类型的

读取一个字符  也就是二个字节

package src.com.atguigu02.filestream;

import org.junit.Test;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * ClassName: FileReaderWriterTest
 * Package: src.com.atguigu02.filestream
 * Description:
 *
 * @Author 小白
 * @Create 2024/4/14 14:59
 * @Version 1.0
 */
public class FileReaderWriterTest {

    /*
     * 需求:读取hello.txt中的内容,显示在控制台上。
     *
     * 异常使用throws的方式处理,不太合适。见 test2()
     * */
/*java.io.FileReader `类用于读取字符文件,构造时使用系统默认的字符编码和默认字节缓冲区。

- `FileReader(File file)`: 创建一个新的 FileReader ,给定要读取的File对象。
- `FileReader(String fileName)`: 创建一个新的 FileReader ,给定要读取的文件的名称。  */


    @Test
    public void test1() throws IOException {

       //1.创建File类的对象,对应着hello.txt文件
        File file = new File("hello.txt");
        //2.创建输入型的字符流对象,用于读取数据
        FileReader fr = new FileReader(file);

        //3.读取数据,并显示在控制台上
        //方式1
//    int data =fr.read();  //先读一个 然后进行判断
//        while (data !=-1){   //然后判断是不是等于-1 如果等于 就不在读
//            System.out.println((char) data);
//            data = fr.read();
//        }

        //方式2
        //data过来 先让fr去reaad 去读一下(helloworld123)第一个文件的第一个"h"是不是 =-1  如果不是输出打印  在返回
        int data;
        while ((data = fr.read()) != -1) {
            System.out.print((char) data);
        }

        //4. 流资源的关闭操作(必须要关闭,否则会内存泄漏)
        fr.close();

         }


    /*
     * 需求:读取hello.txt中的内容,显示在控制台上。
     * 使用try-catch-finally的方式处理异常。确保流一定可以关闭,避免内存泄漏
     * */
    @Test
    public void test2() {
        FileReader fr = null;
        try {
            //1.创建File类的对象,对应着hello.txt文件
            File file = new File("hello.txt");

            //2.创建输入型的字符流,用于读取数据
            fr = new FileReader(file);

            //3.读取数据,并显示在控制台上
            int data;
            while ((data = fr.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 流资源的关闭操作(必须要关闭,否则会内存泄漏)
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

升级版本

int read(char[ ]  cbuf)

每次读取一个字符 就去和磁盘交互  效果太差  所以我们先放在char[ ] 数组里面 在去和磁盘进行交互  效果会好一点   好比快递小哥送快递  要去拿个小车去送 才能送得多

 

   /*
     * 需求:读取hello.txt中的内容,显示在控制台上。
     *
     * 对test2()进行优化,每次读取多个字符存放到字符数组中,减少了与磁盘交互的次数,提升效率。
     *
     * */
    @Test
    public void test3() {
        FileReader fr = null;
        try {
            //1.创建File类的对象,对应着hello.txt文件
            File file = new File("hello.txt");

            //2.创建输入型的字符流,用于读取数据
            fr = new FileReader(file);

            //3.读取数据,并显示在控制台上
            char[] cbuffer = new char[5];
            int len;
            while ((len = fr.read(cbuffer)) != -1) {
                //遍历数组:错误的写法
//                for (int i = 0; i < cbuffer.length; i++) {
//                    System.out.print(cbuffer[i]);
//                }

                //遍历数组:错误的写法
                for (int i = 0; i < len; i++) {
                    System.out.print(cbuffer[i]);
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 流资源的关闭操作(必须要关闭,否则会内存泄漏)
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

读的话 文件要有  而且要有内容读

写 (可以没有 然后去写)    输出流

    /*
     * 需求:将内存中的数据写出到指定的文件中
     * */
    @Test
    public void test4() {
        FileWriter fw = null;
        try {
            //1. 创建File类的对象,指明要写出的文件的名称
            File file = new File("info.txt");

            //2. 创建输出流
            //覆盖文件,使用的构造器:
            fw = new FileWriter(file);
//            fw = new FileWriter(file,false);
            //在现有的文件基础上,追加内容使用的构造器:
//            fw = new FileWriter(file,true);

            //3. 写出的具体过程
            //输出的方法:write(String str) / write(char[] cdata)
            fw.write("I love U!\n");
            fw.write("You love him!\n");
            fw.write("太惨了...");

            System.out.println("输出成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 关闭资源
            try {
                if (fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

读写一起

/*
     * 需求:复制一份hello.txt文件,命名为hello_copy.txt
     * */
    @Test
    public void test5() {
        FileReader fr = null;
        FileWriter fw = null;

        try {
            //1. 创建File类的对象
            File srcFile = new File("hello.txt");
            File destFile = new File("hello_copy.txt");

            //2. 创建输入流、输出流
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);

            //3. 数据的读入和写出的过程
            char[] cbuffer = new char[5];
            int len;//记录每次读入到cbuffer中的字符的个数
            while ((len = fr.read(cbuffer)) != -1) {
                //write(char[] cbuffer,int fromIndex,int len)
                fw.write(cbuffer, 0, len); //正确的
//                fw.write(cbuffer); //错误的
            }

            System.out.println("复制成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. 关闭流资源
            //方式1:
//            try {
            //if (fw != null)
//                  fw.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally {
//
//                try {
            //if (fr != null)
//                    fr.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            //方式2:
            try {
                if (fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

  • 22
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值