IO流原理及流的分类 学习笔记 FileReader和FileWriter

I/O是Input/Output的缩写,用于处理设备之间的数据传输

Java程序中,对于数据的输入/输出操作”流(stream)"的方式进行

Java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流
  1. Java的IO流共涉及40多个类,实际上是从如下4个抽象基类派生的。
  2. 由着四个类派生出来的子类名称都是以其父类名作为子类名后缀。
抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

/**
 * 一。流的分类
 * 1.操作数据单位:字节流,字符流
 * 2.数据流的流向:输入流,输出流
 * 3.流的角色:节点流,处理流
 *
 * 二。流的体系结构
 * 抽象基类             节点流(文件流)                   缓冲流
 * InputStream         FileInputStream         BufferedInputStream
 * OutPutStream        FileOutputStream        BufferedOutputStream
 * Reader              FileReader              BufferedReader
 * Writer              FileWriter              BufferedWriter
 */

 File文件的读取

 
public void testFileReader(){
        FileReader fr = null;

        try {
            //1.实例化File类的对象,指明要操作的文件
            //相较于当前的module
            File file = new File("hello.txt");

            //2.提供具体的流
            fr = new FileReader(file);

            //3.数据的读入
            //read():返回读入的一个字符。如果达到文件末尾,返回-1
            int data = fr.read();
            while (data != -1){
                System.out.print((char)data);
                data = fr.read();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //4.流的关闭操作
            try {
                fr.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
输出结果:
helloworld1

 对read()操作升级:使用read的重载方法

 注意,一开始设置数组的读取长度,可能遇见文件最后一段长度没有数组长度长,所以不能直接  数组.length(),每次读取都是覆盖上一次数组的内容,所以如果最后一次我文件读取长度不够没有完全覆盖会读出来脏数据。

所以通过每次读取的length变量来判断

//对read()操作升级:使用read的重载方法
    @Test
    public void testFileReader1() {
        FileReader fileReader = null;
        try {
            //1.File类的实例化
            File file = new File("hello.txt");
            //2.FileReader流的实例化
            fileReader = new FileReader(file);
            //3.读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,则返回-1
            char [] cbuf = new char[5];
            //4.资源的关闭
            int len;
            while ((len  = fileReader.read(cbuf))!=-1){
                //一种是for循环输出
                for (int i=0;i<len;i++){
                    System.out.println(cbuf[i]);
                }
                //一种是转换为String类型
                String str = new String(cbuf,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
输出结果:
hellohello
worldworld
11

 FileWritre文件的写入

/**
 * 从内存张写出数据到硬盘的文件里。
 *
 * 说明:
 * 1.输出操作,对应的File可以不存在的。并不会报错
 * 2.
 *  File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件
 *  File对应的硬盘中的文件如果存在:
 *              如果流使用的构造器是:FileWriter(file,false)/FileWriter(file):对原有文件的覆盖
 *              如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有的基础上追加内容
 */

    大家注意,fileWriter的执行顺序!!!!!!!!!!!!!

    @Test
    public void testFileWriter() throws IOException {
        //1.提供File类的对象,指明写出到的文件
        File file = new File("hello1.txt");
        //2.提供FileWriter的对象,用于数据的写出
        FileWriter fileWriter = new FileWriter(file);
        FileWriter fileWriter1 = new FileWriter(file,true);

        //3.写出的操作
        fileWriter.write("I have a dream ! \n");
        fileWriter1.write("I have a dream aaaaaa! \n");
        fileWriter.write("you need Fucking dream too!");
        //4.流资源的关闭
        fileWriter.close();
        fileWriter1.close();

    }

 FileReader和FileWriter实现简单的文件复制(文本文件)

    @Test
    public void testFileReaderFileWriter(){
        FileReader fileReader = null;
        FileWriter fileWriter = null;
        try {
            //1.创建File类的对象,指明读入和写出的文件
            File srcFile = new File("hello.txt");
            File srcFile1 = new File("hello1.txt");
            //2.创建输入流和输出流的对象
            fileReader = new FileReader(srcFile);
            fileWriter = new FileWriter(srcFile1,true);
            //3.数据的读入和写出操作
            char[] charbuff = new char[5];
            int len;
            while ((len=fileReader.read(charbuff)) != -1){
                fileWriter.write(new String(charbuff,0,len));
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //4.关闭流资源
            try {
                fileReader.close();
                fileWriter.close();

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

测试FileInputStream和FileOutputStream的使用

* 结论:
* 1。对于文本文件(。txt,.java,.c,.cpp),使用字符流处理
* 2.对于非文本文件(.jpg,mp3,.mp4,.avi,.doc,.ppt),使用字节流处理

public class FileInputOutputStreamTest {

    //使用字节流FileInputStream处理文本文件是可能出现乱码的,中文情况
    @Test
    public void testFileInputStream(){
        FileInputStream fp = null;
        try {
            File file = new File("hello.txt");
            fp = new FileInputStream(file);
            byte[] buffer = new byte[5];
            int len;
            while ((len=fp.read(buffer))!=-1){
                System.out.print(new String(buffer,0,len));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fp.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}
输出结果:helloworld1在���啊与目标 

缓冲流的使用BufferedInputStream BufferedOutputStream

/**
 * 处理流之一:缓冲流的使用
 * 1.缓冲流:
 * BufferedInputStream
 * BufferedOutputStream
 * BufferedReader
 * BufferedWriter
 *
 * 2.作用:提高流的读取,写入的速度
 *
 */

关闭外层流的时候,会自动关闭内层流,所以可以省略关闭内层流的那一步

    /**
     * 实现非文本文件的复制
     */
    @Test
    public void BufferedStreamTest(){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bist = null;
        BufferedOutputStream bost = null;
        try {
            //1.造文件
            File file = new File("2.jpg");
            File file1 = new File("1.jpg");
            //2.造流
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream(file1);
            //2.1造缓冲流
            bist = new BufferedInputStream(fileInputStream);
            bost = new BufferedOutputStream(fileOutputStream);

            //3.复制的细节:读取,写入
            byte[] bytes = new byte[10];
            int len;
            while ((len=bist.read(bytes))!=-1){
                bost.write(bytes,0,len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //4.关闭流
                //要求:先关闭外层的流,在关闭内层的流
                bist.close();
                bost.close();
                //说明:关闭外层的流的同时,内层流也会自动的关闭,所以关闭内层流的关闭可以省略
                //fileInputStream.close();
                //fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

缓冲流与节点流的对比

   /**
     * 实现非文本文件的复制        缓冲流
     */
    @Test
    public void BufferedStreamTest(){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bist = null;
        BufferedOutputStream bost = null;
        try {
            //1.造文件
            File file = new File("1.jpg");
            File file1 = new File("4.jpg");
            //2.造流
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream(file1);
            //2.1造缓冲流
            bist = new BufferedInputStream(fileInputStream);
            bost = new BufferedOutputStream(fileOutputStream);

            //3.复制的细节:读取,写入
            byte[] bytes = new byte[10];
            int len;
            while ((len=bist.read(bytes))!=-1){
                bost.write(bytes,0,len);
                //bost.flush(); 刷新缓冲区
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //4.关闭流
                //要求:先关闭外层的流,在挂你不内层的流
                bist.close();
                bost.close();
                //说明:关闭外层的流的同时,内层流也会自动的关闭,所以关闭内层流的关闭可以省略
                //fileInputStream.close();
                //fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

 //实现文件复制的方法            节点流
    public void copyFileWithBuffered(String srcPath,String destPath){

        FileInputStream fip = null;
        FileOutputStream fop = null;
        try {
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);

            fip = new FileInputStream(srcFile);
            fop = new FileOutputStream(destFile);

            byte[] buffer = new byte[10];
            int len;
            while ((len = fip.read(buffer)) != -1){
                fop.write(buffer,0,len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fip.close();
                fop.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    fip.close();
                    fop.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
 @Test
    public void testCopyFileWithBuffer(){
        long start = System.currentTimeMillis();
        String srcPath="1.jpg";
        String destPath="3.jpg";
        copyFileWithBuffered(srcPath,destPath);
        long end = System.currentTimeMillis();
        System.out.println(end-start);

        long start1 = System.currentTimeMillis();
        BufferedStreamTest();
        long end1 = System.currentTimeMillis();
        System.out.println(end1-start1);
    }

输出结果:
403
10

使用BufferedReader和BufferedWriter实现文本文件的复制

 public void testBufferedReaderBufferedWriter(){
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(new File("hello.txt")));
            bufferedWriter = new BufferedWriter(new FileWriter(new File("bufferread.txt")));

            //方式一:使用[char]数组
            //int len;
            //char[] c =new char[5];
            //
            //while ((len=bufferedReader.read(c))!=-1){
            //    bufferedWriter.write(new String(c),0,len);
            //}
            //方式二:使用string readline读取一行
            String data;
            while((data = bufferedReader.readLine())!=null){
                //方法一 实现换行
                //bufferedWriter.write(data+"\n");
                //方法二 实现换行
                bufferedWriter.write(data);
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bufferedReader.close();
                bufferedWriter.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

 处理流之二:转换流的使用

/**
 * 处理流之二:转换流的使用
 * 1.转换流:属于字符流
 * InputStreamReader:将一个字节的输入流转换成字符的输入流
 * OutputStreamWriter:将一个字符的输出流转换为字节的输出流
 * 2.作用:提供字节流与字符流之间的转换
 *
 * 3.解码:字节,字节数组-->转换为字符串,字符数组
 *   编码:字符串,字符数组-->转换为字节,字节数组
 */

 InputStream实现字节流到字符流的转换

/**
     *InputStream实现字节流到字符流的转换
     */
    @Test
    public void test1() throws IOException {
        FileInputStream fip = new FileInputStream("hello.txt");

        //使用系统默认字符集
        //InputStreamReader inputStreamReader = new InputStreamReader(fip);
        //选择自己所需的字符集
        InputStreamReader inputStreamReader = new InputStreamReader(fip,"utf-8");
        char[] c = new char[20];
        int len;
        while ((len=inputStreamReader.read(c))!= -1){
            String str = new String(c,0,len);
            System.out.println(str);
        }

        inputStreamReader.close();
    }

综合使用InputStream和OutputStreamWriter,实现写入编码格式改变

/**
     * 综合使用InputStream和OutputStreamWriter
     */
    @Test
    public void test2(){
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            File file1 = new File("hello.txt");
            File file2 = new File("hello-copy.txt");

            FileInputStream fileInputStream = new FileInputStream(file1);
            FileOutputStream fileOutputStream = new FileOutputStream(file2);

            isr = new InputStreamReader(fileInputStream,"utf-8");
            osw = new OutputStreamWriter(fileOutputStream,"GBK");

            char[] c = new char[5];
            int len;
            while ((len = isr.read(c))!=-1){
                osw.write(c,0,len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                isr.close();
                osw.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值