Java之IO流

IO流详解



一、File类的使用

File类的理解:
1、File类的一个对象,代表一个文件或一个文件目录
2、File类声明在java.io包下
3、File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法, 并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成

1.1File类常用构造器

方法名称说明
File(String pathname)通过将给定的路径名,字符串转换为抽象路径名来创建新的File实例
File(String parent,String child)从父路径名,字符串和子路径名,字符串创建新的File实例
File(File parent,String child)从父抽象路径名和子路径名,字符串创建新的File实例
package com.nnfx.day01;

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

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 16:24
 * 创建文件
 */
public class Test02 {
    public static void main(String[] args) throws IOException {
        /**
         * mkdir 创建文件夹
         * createNewFile 创建文件的
         */
        //需求:在D:\FileTest 目录中创建一个File.java
        File file1 = new File("D:\\FileTest\\File.java");
        //createNewFile() 如果成功创建文件 返回true 否则返回false
        //当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
        System.out.println(file1.createNewFile());

        //需求:在D:\FileTest创建day01文件
        //创建由此抽象路径名命名的目录
        //判断该文件是否存在,如果存在,就创建,返回true,创建失败则返回false
        File file2 = new File("D:\\FileTest\\day01");
        System.out.println(file2.mkdir());

        //需求:在D:\FileTest\day02\javaweb
        //创建由此抽象路径命名的目录,包括任何必需但不存在的父目录
        File file3 = new File("D:\\FileTest\\day02\\javaweb");
        System.out.println(file3.mkdirs());
    }
}

1.2 File类创建功能

方法名称作用
public boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir()创建由此抽象路径名命名的目录
public boolean mkdirs()创建由此抽象路径命名的目录,包括任何必需但不存在的父目录
package com.nnfx.day01;

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

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 16:24
 * 创建文件
 */
public class Test02 {
    public static void main(String[] args) throws IOException {
        /**
         * mkdir 创建文件夹
         * createNewFile 创建文件的
         */
        //需求:在D:\FileTest 目录中创建一个File.java
        File file1 = new File("D:\\FileTest\\File.java");
        //createNewFile() 如果成功创建文件 返回true 否则返回false
        //当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
        System.out.println(file1.createNewFile());

        //需求:在D:\FileTest创建day01文件
        //创建由此抽象路径名命名的目录
        //判断该文件是否存在,如果存在,就创建,返回true,创建失败则返回false
        File file2 = new File("D:\\FileTest\\day01");
        System.out.println(file2.mkdir());

        //需求:在D:\FileTest\day02\javaweb
        //创建由此抽象路径命名的目录,包括任何必需但不存在的父目录
        File file3 = new File("D:\\FileTest\\day02\\javaweb");
        System.out.println(file3.mkdirs());
    }
}

1.3 File类的判断方法

方法名称作用
boolean isDirectory()判断是否是文件夹
boolean isFile()判断是否是文件
boolean exists()判断文件是否存在
package com.nnfx.day01;

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

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 16:43
 * 判断方法
 */
public class Test03 {
    public static void main(String[] args) throws IOException {
        File file1 = new File("D:\\FileTest\\File.java");
        //file1.isDirectory() 返回是为true 就说明它是文件夹 返回false 就不是文件夹
        if (file1.isDirectory()) {
            System.out.println("是文件夹");
        }else {
            System.out.println("不是文件夹");
        }
        //file1.isFile() 返回true 说明就是一个文件 返回false 就不是一个文件
        if (file1.isFile()) {
            System.out.println("是一个文件");
        }else {
            System.out.println("不是一个文件");
        }
        //如果该文件存在就返回true 不存在就返回false
        if (file1.exists()) {
            System.out.println("存在");
        }else {
            System.out.println("不存在");
            file1.createNewFile();
            System.out.println("程序自动创建该文件");
        }
    }
}

1.4 File类的获取方法

方法名称作用
String getAbsolutePath()获取绝对路径
String getPath()获取抽象路径名转化路径名字符串
String getName()获取文件或文件夹的名称
String[] list()获取目录下所有内容,返回字符串数组
File[] listFiles()获取目录下的所有内容,返回File对象数组
package com.nnfx.day01;

import java.io.File;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 16:53
 * 获取方法
 */
public class Test04 {
    public static void main(String[] args) {
        File file = new File("D:\\FileTest\\");
        //file.getAbsoluteFile() 获取该file类 完整路径地址 绝对路径
        System.out.println(file.getAbsoluteFile());
        //file.getPath()获取抽象路径名转化路径名字符串
        System.out.println(file.getPath());
        //如果该路径是一个文件路径,获取到的就是 文件名称.后缀  如果该路径是一个文件夹路径 获取到的就是文件夹名称
        System.out.println(file.getName());
        System.out.println("---------返回字符串类型----------");
        String[] list = file.list();
        for (String str : list) {
            System.out.println(str);
        }
        System.out.println("---------返回文件类型----------");
        File[] files = file.listFiles();
        for (File f : files) {
            System.out.println(f.getName());
        }
    }
}

1.5 File类的删除方法

方法名称·作用
boolean delete()如果删除路径是一个目录,不能够直接删除目录,需要先删除该目录中所有内容,最后在删除目录。如果删除路径是一个文件可以直接删除
package com.nnfx.day01;

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

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 17:20
 * 删除方法
 */
public class Test06 {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\FileTest\\day03\\file.java");
        System.out.println(file.createNewFile());
        //删除文件或文件夹
        //file.delete()删除文件或文件夹
        /**
         * 如果删除的路径是一个文件路径,则直接删除
         * 如果删除的路径是一个文件夹路径,则需要先将该文件夹里面的内容删除 才可以删除该文件夹
         */
        System.out.println(file.delete());
    }
}

循环删除多个文件

package com.nnfx.day01;

import javax.xml.transform.Source;
import java.io.File;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 17:31
 * 循环删除多个文件
 */
public class Test07 {
    public static void main(String[] args) {
        File file = new File("D:\\FileTest\\day03");
        //判断该路径 如果是 文件夹路径 则删除多个文件
        if (file.isDirectory()) {
            System.out.println("删除路径是一个文件夹路径");
            deletes(file);
        }

        //判断该路径 如果是文件路径
        if (file.isFile()) {
            System.out.println("删除路径是一个文件");
            delete(file);
        }

    }
    public static void deletes(File file) {
        //1、获取到该目录中的所有文件
        File[] files = file.listFiles();
        for (File f : files) {
            f.delete();
            System.out.println("删除文件:" + f.getAbsolutePath());
        }
        //2、删除目录
        file.delete();
        System.out.println("删除目录:" + file.getAbsolutePath());
    }

    public static void delete(File file) {
        file.delete();
        System.out.println("删除文件" + file.getAbsolutePath());
    }
}

1.6 绝对路径和相对路径

绝对路径:物理硬盘真实存的路径
相对路径:相对路径是java工程中要访问的文件相对于当前文件的位置

package com.nnfx.day01;

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

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 17:04
 * 绝对路径 相对路径
 */
public class Test05 {
    public static void main(String[] args) throws IOException {
        
        File file = new File("file.java");
        //底层自动填充绝对路径 获取当前项目路径
        //D:\IOFile\file.java
        System.out.println(file.createNewFile());
        //获取绝对路径
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getPath());
        /**
         * 绝对路径是写死的 如果将代码放入到其他电脑上运行 如果该电脑没有这个路径 就会报错
         * 相对路径:动态获取运行项目路径--灵活
         *
         */
    }
}

二、IO流原理及流的分类

1、 I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输
2、Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行
3、java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据

原理示意图
在这里插入图片描述

抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

.根据数据流向分类

数据流向作用
输入流读数据 将硬盘中的数据读取到内存中
输出流写数据 将程序中的数据写入到硬盘中

按照数据类型来分

数据类型作用
字节流字节输入流/字节输出流
字符流字符输入流/字符输出流

说明:
1、纯文本文件,优先使用字符流
2、图片、视频、音频等二进制文件,优先使用字节流
3、在我们不确定内容是什么,优先使用字节流

三、字节流

3.1 字节流写入数据

抽象类说明
InputStream字节输入流的所有类的超类
OutputStream字节输出流的所有类的超类子类名
FileOutputStream文件输出流用于将数据写入File
.FileOutputStream(Stringname)创建文件输出流以指定的名称写入文件

字节流写入数据常用的三种方式

方法名称说明
void write(int b)将指定的字节写入此文件输出流 一次写一个字节数据
void write(byte[] b)将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
void write(byte[] b, int off, int len)将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据

说明:程序中出现的异常需要使用try-catch-finally处理。

package com.nnfx.day01;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 23:17
 * 正确关闭IO流
 */
public class Test14 {
    public static void main(String[] args) {
        FileOutputStream f = null;
        try {
            f = new FileOutputStream("file.txt");
            f.write("abcde".getBytes());
            int j = 1 / 0;

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

        }
    }
}

方法一:

package com.nnfx.day01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 22:02
 * 字节输出流
 */
public class Test11 {
    /**
     * 将程序中的数据写入到磁盘中
     * @param args
     */
    public static void main(String[] args) throws IOException {
        //指定写入文件的路径 需要抛出异常
        /**
         * 1、调用系统功能创建文件 mybatis.txt
         * 2、创建字节输出流对象
         * 3、字节输出流对象指向文件
         */
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\FileTest\\day02\\mybatis.txt");
        //写入数据到磁盘中
        fileOutputStream.write(98);
        //关闭字节输出类
        fileOutputStream.close();
    }
}

方法二:

package com.nnfx.day01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 22:29
 * 字节流写入数据的三种方式
 */
public class Test12 {
    /**
     * 使用输出流写入数据的三种方式
     * @param args
     */
    public static void main(String[] args) throws IOException {
        /**
         * 创建FileOutputStream
         * 直接调用到FileOutputStream("路径") 底层就是 new File("file.txt")
         * byte[] bytes = {97, 98, 99, 100}; 直接写入字节数组的数据到磁盘当中 效率非常高
         */
        FileOutputStream fileOutputStream = new FileOutputStream(new File("file.txt"));
        
        byte[] bytes = {97, 98, 99, 100};
        fileOutputStream.write(bytes);

        //关闭资源
        fileOutputStream.close();
    }
}

方法三:

package com.nnfx.day01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 22:29
 * 字节流写入数据的三种方式
 */
public class Test12 {
    /**
     * 使用输出流写入数据的三种方式
     * @param args
     */
    public static void main(String[] args) throws IOException {
        /**
         * 创建FileOutputStream
         * 直接调用到FileOutputStream("路径") 底层就是 new File("file.txt")
         * byte[] bytes = {97, 98, 99, 100}; 直接写入字节数组的数据到磁盘当中 效率非常高
         */
        FileOutputStream fileOutputStream = new FileOutputStream(new File("file.txt"));
       
        byte[] bytes = {97, 98, 99, 100};
        fileOutputStream.write(bytes,1,bytes.length-1);//98 99 100

        //关闭资源
        fileOutputStream.close();
    }
}

3.2 字节流写入数据换行和追加写

1、定义文件路径时,注意:可以用“/”或者“\”
2、在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖
3、如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容

package com.nnfx.day01;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 22:45
 * 字节流写入数据换行和追加写
 */
public class Test13 {
    public static void main(String[] args) throws IOException {
        /**
         * 第二个参数如果是为true,则表示追加写入数据
         */
        FileOutputStream f = new FileOutputStream("file.txt",true);

        for (int i = 0;i < 10;i++) {
            f.write("12345".getBytes());
            //换行
            f.write("\n".getBytes());
        }
        f.close();
    }
}

3.3 字节流读取数据

读取磁盘中我们想要的文本内容,并且在控制台输出,我们可以通过FileInputStream读取磁盘文件中的数据

抽象类说明
FileInputStream从文件系统中的文件获取输入字节
FileInputStream(String name)通过打开与实际文件的连接来创建一个FileInputStream,该文件有文件系统中的路径名name命名

步骤:
1、创建字节输入流对象
2、调用字节输入流对象的读数据方法
3、释放资源

字节流读取数据

方法名称说明
int read()从该输入流读取一个字节数据,返回值为-1时说明文件读取完毕

说明点: 1、 read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
2、异常的处理:为了保证流资源一定可以执行关闭操作。要使用try-catch-finally处理 3、
读入的文件一定要存在,否则就FileNotFoundException

package com.nnfx.day01;

import javax.security.auth.callback.CallbackHandler;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-06 23:31
 * FileInputStream单个字节读取文件
 *
 */
public class Test15 {
    public static void main(String[] args)  {
        FileInputStream fileInputStream = null;
        try {
//            //1、创建FileInputStream 输入流 读取磁盘中的数据到内存中
            fileInputStream = new FileInputStream("D:\\IOFile\\spring.txt");
            System.out.println("读取到的文件内容:");

            int read;
            /**
             *1、 read = fileInputStream.read() 表示赋值操作
             *2、 read != -1
             */
            while ((read = fileInputStream.read()) != -1) {
                System.out.print((char) read);
            }
             System.out.println();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //3、释放资源
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.4 字节流复制数据

当我们需要把某一个文件目录下的文本拷贝到另一个文件的目录下,这时就可以使用到字节流复制数据进行操作

package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 14:23
 * 字节流文件内容拷贝
 */
public class Test16 {
    public static void main(String[] args) throws IOException {
        //1、需要读取到磁盘中的 D:\IOFile\java1\java.txt 文件到内存中
        FileInputStream input = new FileInputStream("D:\\IOFile\\java1\\java.txt");
        //2、需要将该内容写入到 D:\IOFile\java2\java.txt
        FileOutputStream output = new FileOutputStream("D:\\IOFile\\java2\\java.txt");
        int by;
        while ((by=input.read())!=-1) {
            output.write(by);
        }
        //3、释放资源
        input.close();
        output.close();
    }
}

3.5 字节流读取字节数组数据

package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 20:18
 * 字节流读取字节数组数据
 */
public class Test18 {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\IOFile\\spring.txt");

        byte[] bytes = new byte[1024]; //整数倍数

        int len;
        /**
         * 读取到数据 字节数组长度 >0
         * 如果没有读取到数据 -1
         * 循环形式读取数据 每次以1024字节读取数据
         * 如果能够读取到数据 len>0 true
         * 将该数据转化为string类型
         * 如果能够读取不到数据 len-1 false
         * != -1 读取不到数据
         */
        while ((len = inputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes,0,len));
        }
        inputStream.close();
    }
}

3.6 字节流复制图片

当我们需要把某一个文件目录下的图片拷贝到另一个文件的目录下,这时就可以使用到字节流复制图片进行操作

package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 20:35
 * 字节流复制图片
 */
public class Test19 {
    public static void main(String[] args) throws IOException {
        //1、程序需要读取将D:\IOFile\java1\pic.jpg 到程序中
        FileInputStream fileInputStream= new FileInputStream("D:\\IOFile\\java1\\pic.jpg");
        byte[] bytes = new byte[1024];
        int len;
        //2、再将该图片写入到D:\IOFile\java2\目录
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\IOFile\\java2\\pic.jpg");
        while ((len=fileInputStream.read(bytes)) != -1)  {
            fileOutputStream.write(bytes,0,len);
        }

        //3、关闭资源
        fileInputStream.close();
        fileOutputStream.close();
    }
}

四、字符流

字符流:就是在字节流的基础上,加上编码,形成的数据流

字符流底层还是用的字节流,字符流仅仅做字符和字节的转换!接收一个字节流,生成的一个字符流。把字节流转换为字符流。底层会用字节流去硬盘读取字节数据,把字节数据转换为字符数据,然后返回。实现了把字节数据转换为字符数据

4.1 字符流写入数据

方法名称作用
public void write(int c)写出一个字符
public void write(char[] cbuf)写出字符数组
public void write(char[] cbuf,int off,int len)写出字符数组cbuf中,从off开始,共len个字符
public void write(String str)写出字符串
public void write(String str,int off,int len)写出字符串,从off开始,共len个字符
package com.nnfx.day01;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 14:24
 * 字符流写入数据
 */
public class Test24 {
    public static void main(String[] args) throws IOException {
        //1、在D:\IOFile\spring.txt 文本内容写入 中华人民共和国万岁 中国共产党万岁 中国人民万岁
        //字符流:对字节流包装
        //创建输出写入字符流
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\spring.txt"));
        outputStreamWriter.write("中华人民共和国万岁\n中国共产党万岁\n中国人民万岁");
        outputStreamWriter.close(); //关闭资源
    }
}

package com.nnfx.day01;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 14:42
 * public void write(char[] cbuf)
 */
public class Test26 {
    public static void main(String[] args) throws IOException {
        //创建一个字符输出流对字节输出流做包装
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\springboot.txt"));

        //写出字符数组cbuf中,从off开始,共len个字符
        //参数1 char类型数组
        //参数2 从什么位置开始写入数据 index=3
        //参数3 需要写入几个字符
        char[] chars = {'a','b','c','中','国'};
        outputStreamWriter.write(charss,3,2);
        
        outputStreamWriter.close();
    }
}

package com.nnfx.day01;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 14:42
 * public void write(String str,int off,int len)
 */
public class Test26 {
    public static void main(String[] args) throws IOException {
        //创建一个字符输出流对字节输出流做包装
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\springboot.txt"));

        //写出字符串,从off开始,共len个字符
        outputStreamWriter.write("中华人民共和国万岁",0,7);
        outputStreamWriter.close();
    }
}

4.2 字符流读取数据

方法名称作用
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据
package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 15:01
 * 字符流读取数据
 */
public class Test27 {
    public static void main(String[] args) throws IOException {
        //1、创建字节输入流(字符输入流 底层基于字节输入流)
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\springboot.txt"));
        //读取单个字符
       int read1 = inputStreamReader.read();
       System.out.println((char)read1);
       
        inputStreamReader.close();
    }
}

package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 15:01
 * 字符流读取数据
 */
public class Test27 {
    public static void main(String[] args) throws IOException {
        //1、创建字节输入流(字符输入流 底层基于字节输入流)
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\springboot.txt"));
        
        //一次读一个字符数组数据
        char[] chars = new char[1024];
        //单次以1024个字符数组读取数据 返回值 就是实际读取到长度
        int len = inputStreamReader.read(chars);
        System.out.println("实际读取到的长度:" + len);
        System.out.println(new String(chars,0,len));
        inputStreamReader.close();
    }
}

4.3 字符流拷贝文本文件

package com.nnfx.day01;

import java.io.*;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 15:21
 * 字符流拷贝文本文件
 */
public class Test28 {
    public static void main(String[] args) throws IOException {
        //1、使用字符流 读取到 D:\IOFile\java1\java.txt 到程序中
        //字符输入流
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\IOFile\\java1\\java.txt"));
        //字符输出流
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\IOFile\\java2\\java.txt"));
        char[] chars = new char[1024];
        int len;
        while ((len = inputStreamReader.read(chars)) != -1) {
            //2、将读取到文本文件内容写入到D:\IOFile\java2\ 目录下
            outputStreamWriter.write(chars,0,len);
        }
        inputStreamReader.close();
        outputStreamWriter.close();
    }
}

五、缓冲流

1、当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
2、当使用BufferedInputStream读取字节文件时BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组
3、向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
4、关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
5、如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出

作用:
提供流的读取、写入的速度

5.1 字节缓冲流

数据类型说明
BufferedInputStream字节缓冲输入流
BufferedOutputStream字节缓冲输出流
package com.nnfx.day01;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 21:05
 * 字节缓存输入流
 */
public class Test21 {
    public static void main(String[] args) throws IOException {
        //1、创建了一个字节输入流对象 指定读取磁盘文件路径
        FileInputStream fileInputStream = new FileInputStream("D:\\IOFile\\java1\\springboot.txt");
        //2、创建了一个BufferedInputStream 指定 fileInputStream
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        //3、申请以块的形式读取数据
        int len;
        byte[] bytes = new byte[1024];
        while ((len = bufferedInputStream.read(bytes)) != -1) {
            //len 实际读取到的数据
            System.out.println(new String(bytes,0,len));
        }
        bufferedInputStream.close();
    }
}

package com.nnfx.day01;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 20:51
 * 字节缓存输出流
 */
public class Test20 {
    public static void main(String[] args) throws IOException {
        //输出流 写入数据到磁盘中
        //1、创建一个字节输出流对象 填写写入数据 磁盘路径
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\IOFile\\java1\\springboot.txt");
        //2、创建的字节缓存区输出流 在构造方法中传递的 字节输出流对象---- 因为字节缓冲流输出流本质对字节流封装以块的形式写入数据
        //字节缓冲流 缓冲区的默认大小为8192字节 8KB
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bufferedOutputStream.write("abcdefg\nhijklmn".getBytes());
        bufferedOutputStream.close();
    }
}

5.2 字节缓冲流复制视频

package com.nnfx.day01;

import javafx.util.converter.ByteStringConverter;

import java.io.*;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 21:12
 * 字节缓冲区复制视频
 */
public class Test22 {
    public static void main(String[] args) throws IOException {
        //原理:
        /**
         * 1、程序需要读取到磁盘中:D:\IOFile\java1\video.mp4 到内存中
         * 2、将视频写入到D:\IOFile\java2\目录
         */
        //创建字节输入缓冲流
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\\IOFile\\java1\\video.mp4"));
        //创建字节输出缓冲流
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\IOFile\\java2\\video.mp4"));
        int len;
        byte[] bytes = new byte[1024];
        while ((len=bufferedInputStream.read()) != -1) {
            //输出到D:\IOFile\java2\
            bufferedOutputStream.write(bytes);
        }
        //关闭资源
        bufferedInputStream.close();
        bufferedOutputStream.close();
    }
}

5.3 字符缓冲流

数据类型说明
BufferedWriter字符缓冲写入流
BufferedReader字符缓冲输入流

1、BufferedReader:从字符输入流读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
2、将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

package com.nnfx.day01;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 16:20
 * 字符缓冲流写入数据换行操作
 */
public class Test31 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\IOFile\\a.txt"));
        for (int i = 1;i<=10; i++) {
            bufferedWriter.write("lisi:" + i);
            bufferedWriter.newLine();
        }
        bufferedWriter.close();
    }
}

package com.nnfx.day01;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 16:21
 * 字符缓冲流读取数据换行操作
 */
public class Test32 {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\IOFile\\a.txt"));
        
        String s;
        while ((s = bufferedReader.readLine()) != null) {
            System.out.println(s);
        }
        bufferedReader.close();
    }
}

5.4 字符缓冲流复制文本文件

package com.nnfx.day01;

import java.io.*;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 16:22
 * 字符缓冲流拷贝
 */
public class Test33 {
    public static void main(String[] args) throws IOException {
        //1、需要将硬盘中的Test01.java 读取到程序中
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\IOFile\\java1\\Test01.java"));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\IOFile\\java2\\Test01.java"));
        //2、一行一行读取数据
        String s;
        while ((s = bufferedReader.readLine()) != null) {
                        bufferedWriter.write(s);
            bufferedWriter.newLine();
        }
        bufferedReader.close();
        bufferedWriter.close();
    }
}

5.5 编码和解码

编码表的由来:
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表

编码说明
ASCII美国标准信息交换码, 用一个字节的7位可以表示
ISO8859-1拉丁码表。欧洲码表用一个字节的8位表示
GB2312中国的中文编码表。最多两个字节编码所有字符
GBK中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
Unicode国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示
UTF-8变长的编码方式,可用1-4个字节来表示一个字符

Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16

编码:把我们能看懂的变成看不懂的(字符 --> 字节)
解码:把我们看不懂的变成能看懂的(字节 --> 字符)
乱码原因:编码和解码的码表不一致

package com.nnfx.day01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-07 21:49
 * 编码和解码
 */
public class Test23 {
    public static void main(String[] args) throws IOException {
        /**
         * 读取磁盘中的文件乱码
         * 程序中设定读取编码的格式 UTF-8
         * 该文件存储在硬盘中 编码格式UTF-8
         * 读取中文字符的时候 会发生乱码
         *
         * 字符->字节 编码   字节->字符 解码
         */
        FileInputStream fileInputStream = new FileInputStream("D:\\IOFile\\nnfx.txt");
        byte[] bytes = new byte[1024];
        int len = fileInputStream.read(bytes);
        System.out.println(new String(bytes,0,len,"GBK"));
        fileInputStream.close();
    }
}

六、转换流

转换流提供了在字节流和字符流之间的转换

数据流说明
InputStreamReader将字节输入流转为字符输入流,继承自Reader
OutputStreamWriter将字符输出流转为字节输出流,继承自Writer

FileWriter 类从 OutputStreamWriter 类继承而来。该类按字符向流中写入数据

ileReader类从InputStreamReader类继承而来。该类按字符读取流中数据

package com.nnfx.day01;

import java.io.*;

/**
 * @author 杰仔正在努力
 * @create 2022-12-08 15:30
 * 转换流
 * 使用FileWriter和FileReader 将D:\\IOFile\\java1\\java.txt 文本文件拷贝到D:\\IOFile\\java2\\目录下
 */
public class Test29 {
    public static void main(String[] args) throws IOException {
//        //FileWriter 写入数据
//        //FileWriter 读取数据 -- 字符输入流读取数据  字符输入(编码和解码)-> 字节输入流
//        //jdk进行二次封装 对字节流封装只需要传递路径即可

        FileReader fileReader = new FileReader("D:\\IOFile\\java1\\java.txt");
        FileWriter fileWriter = new FileWriter("D:\\IOFile\\java2\\java.txt");
        int len;
        char[] chars = new char[1024];
        while ((len = fileReader.read(chars)) != -1) {
            fileWriter.write(chars,0,len);
        }
        fileReader.close();
        fileWriter.close();
        //总结:FileReader和 FileWriter 就是对当前字符流对象做了二次封装 不需要传递字节流对象了
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值