缓冲流和转换流的使用【 File类+IO流知识回顾③】

简介: 这篇文章介绍了Java中缓冲流(BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)和转换流(InputStreamReader, OutputStreamWriter)的使用,包括它们的构造方法和如何利用它们提高IO操作的效率及处理字符编码问题。

缓冲流

简单的说就是缓冲流在原有的流上进一步增强,读写效率更高
字节缓冲流:BufferedInputStream, BufferedOutputStream
字符缓冲流:BufferedReader, BufferedWriter

字节缓冲流

BufferedInputStream 构造方法:
image.png
BufferedOutputStream 构造方法:
image.png
构造方法使用:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("文件位置"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("文件位置"));

字节缓冲流复制文件和普通输入输出流对比

public static void fileCopy1(String sourceFilePath,String targetFilePath){
   
    // 1.创建输入输出流对象
    FileInputStream fis = null;
    FileOutputStream fos = null;
    long start = System.currentTimeMillis(); // 复制开始起始时间
    try{
   
        fis = new FileInputStream(sourceFilePath);
        fos = new FileOutputStream(targetFilePath);

        // 2.定义len和byte数组
        int len;
        byte b[] = new byte[1024];

        // 3.循环读入并且输出
        while ((len=fis.read(b))!=-1){
   
            fos.write(b,0,len);
        }
    }catch (IOException e){
   
        System.out.println(e.getMessage());
    }finally {
   
        long end = System.currentTimeMillis(); // 复制结束时间
        try{
   
            if(fis!=null){
   
                fis.close();
            }
            if(fos!=null){
   
                fos.close();
            }
        }catch (IOException e){
   
            System.out.println(e.getMessage());
        }
        long during = end - start;

        System.out.println("copy完毕,耗时"+during);
    }
}
public static void fileCopy2(String sourceFilePath,String targetFilePath) throws IOException {
   
    // 创建流对象
    FileInputStream fis = new FileInputStream(sourceFilePath);
    FileOutputStream fos = new FileOutputStream(targetFilePath);
    // 创建缓冲流对象
    BufferedInputStream bis = new BufferedInputStream(fis);
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    // 设置len和byte数组
    int len;
    byte b[] = new byte[1024];

    long start = System.currentTimeMillis();

    while ((len=bis.read(b))!=-1){
   
        bos.write(b,0,len);
    }
    bis.close();
    bos.close();

    long end = System.currentTimeMillis();

    System.out.println("copy完毕,耗时"+(end-start));
}

main方法测试,缓冲流比普通流快了3倍,这还是在复制185MB文件的情况下,

public static void main(String[] args) throws IOException {
   
    // 测试文件地址 "D:\download\baidudisk\jdk-8u211-linux-x64.tar.gz"  185MB
    String srcPath = "D:\\download\\baidudisk\\jdk-8u211-linux-x64.tar.gz";
    String optPath = "D:\\jdk.tar.gz.bk";
    // fileCopy1(srcPath,optPath); // copy完毕,耗时1101

    fileCopy2(srcPath,optPath); // copy完毕,耗时337
}

字符缓冲流

BufferedReader
image.png
BufferedWriter
image.png
构造方法使用:

BufferedReader bfr = new BufferedReader(new FileReader("文件位置"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("文件位置"));

字符缓冲流的基本方法与普通字符流调用方式一致,但是字符缓冲流具备特有方法:

  1. BufferedReader : public String readLine() 读取一行数据,读取到最后返回null
  2. BufferedWriter:public void newLine() 换行,由系统属性定义符号
String filePath = "D:\\bfr.txt";
FileReader fr = null;
fr = new FileReader(filePath);
BufferedReader bfr = new BufferedReader(fr);
String readLine = null;
while ((readLine = bfr.readLine())!=null) {
   
    System.out.println(readLine);
}
bfr.close();
String filePath = "D:\\bfw.txt";
BufferedWriter bfw  = new BufferedWriter(new FileWriter(filePath));
// 先输出三次换行
bfw.newLine();
bfw.newLine();
bfw.newLine();
// 输出内容
bfw.write("中文。wwwwww");
bfw.close();

转换流

image.png
转换流即处理字节和字符的转换,也称之为编码和解码。
编码:字符->字节
解码:字节->字符

需要会使用的两个类 InputStreamReader 和 OutputStreamWriter ,从字面意思上不难理解,InputStreamReader 是 字节流到字符流的一个桥梁,OutputStreamWriter则是字符流到字节流的桥梁


InputStreamReader

image.png
InputStreamReader是Reader的子类。

  1. 构造方法
方法名称 功能描述
public InputStreamReader(InputStream in) 创建一个使用默认字符集的字符流
public InputStreamReader(InputStream in, final String enc) 创建一个指定字符集的字符流
public InputStreamReader(InputStream in, CharsetDecoder dec) 创建一个指定解码字符集的字符流
public InputStreamReader(InputStream in, Charset charset) 创建一个指定字符集的字符流
  1. 利用转换流解决编码问题

编码问题的引入
首先,写一个txt,编码方式为GB18030,然后尝试使用字符缓冲流进行读入。

image.png

String filePath = "D:\\bfr2.txt";
BufferedReader bfr = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = bfr.readLine())!=null){
   
    System.out.println(line);
}
bfr.close();

从控制台窗口中看到,读取的字符都乱码了…此时为了应对不同编码文件的读入,我们就该使用字符转换流了。

image.png


下面是字符转换流的写法:

String filePath = "D:\\bfr2.txt";
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "GBK");

int len ; 
while ((len= isr.read())!=-1){
   
    System.out.print((char) len);
}
isr.close();

image.png
字符转换流完美的解决了因为编码不同导致乱码的问题。


OutputStreamWriter

image.png
OutputStreamWriter是Writer的子类,是字符流到字节流的桥梁,将字符输出流转换为字节输出流。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

  1. 构造方法
public OutputStreamWriter(OutputStream out) 创建一个使用默认字符集的字符流
public OutputStreamWriter(OutputStream out, String charsetName) 创建一个指定字符集的字符流
public OutputStreamWriter(OutputStream out, Charset cs) 创建一个指定字符集的字符流
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建一个指定编码的字符流
  1. 指定编码输出文本
String optFilePath = "D:\\opsw.txt";
OutputStreamWriter opsw = new OutputStreamWriter(new FileOutputStream(optFilePath),"GBK");
opsw.write("中文-------编码GBK....");
opsw.write("123456");
opsw.write("abcdef");
opsw.close();

image.png


相关文章
|
20天前
|
存储 Java 调度
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
这篇文章回顾了Java中FileInputStream、FileOutputStream、FileReader和FileWriter类的基本使用方法,包括读取和写入文件的操作,以及字符流和字节流的区别和应用场景。
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
|
20天前
|
Java
File类的基本使用【 File类+IO流知识回顾①】
这篇文章回顾了Java中File类的基本使用,包括创建File对象、获取文件数据信息、判断文件存在与否、创建和删除文件目录,以及遍历文件目录的方法。
File类的基本使用【 File类+IO流知识回顾①】
|
20天前
|
存储 Java
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
这篇文章介绍了Java中ObjectInputStream和ObjectOutputStream类的基本使用,这两个类用于实现对象的序列化和反序列化。文章解释了序列化的概念、如何通过实现Serializable接口来实现序列化,以及如何使用transient关键字标记不需要序列化的属性。接着,通过示例代码演示了如何使用ObjectOutputStream进行对象的序列化和ObjectInputStream进行反序列化。
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
|
27天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
2月前
|
Java
IO流操作-------File类、输入流和输出流(二)
这篇文章介绍了Java中IO流操作的基本概念和使用,包括字节流和字符流的读取与写入,以及如何使用缓冲流提高文件读写效率和实现文件复制的方法。
IO流操作-------File类、输入流和输出流(二)
|
2月前
|
Java
IO流操作-------File类(一)
这篇文章介绍了Java中File类的常用操作,包括创建文件/文件夹、删除文件、查询文件属性(如存在性、大小、名称、路径)以及递归遍历文件夹下所有文件的方法。
IO流操作-------File类(一)
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
3月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
2月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
31 2
|
2月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。