Java 进阶IO流(二)

简介: Java 进阶IO流

一、字符流

1、FileReader文件字符写入流

把磁盘中的数据以字符的形式读入到内存中

构造器 解释

public FileReader(File file) 创建字符输入流管道与源文件对象接通

public FileReader(String pathname) 创建字符输入流管道与源文件路径接通

方法名 解释

public int read() 每次读取一个字符,没有字符返回-1

public int read(char[] buffer) 每次读取一个字符数组,没有字符返回-1

2fad2b9e80bfe0d28f152fb7ca54ca4.png

import java.io.FileReader;
import java.io.IOException;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        int read = 0;
        //创建一个读入数据的相对路径的流
        FileReader fileReader = new FileReader("data/access.log");
        //直接读取字符输出
//        while((read = fileReader.read()) != -1){
//            System.out.printf("%c",read);
//        }
        //根据数组存储要求输出
        char[] by = new char[8];
        while((read = fileReader.read(by)) != -1){
            System.out.println(by);
        }
        //关闭读入流
        fileReader.close();
    }
}

2、FIleWriter文件字符输出流

把内存中的数据以字符的形式写出到磁盘中

构造器

构造器 解释

public FileWriter(File file) 创建字符输出流管道与源文件对象接通

public FileWriter(File file,boolean append) 创建字符输出流管道与源文件对象接通,

可追加数据

public FileWriter(String filepath) 创建字符输出流管道与源文件路径接通

public FileWriter(String filepath,boolean append) 创建字符输出流管道与源文件路径接通,

可追加数据

常用方法

方法名 解释

void write(int c) 写一个字符

void write(char[] cbuf) 写入一个字符数组

void write(char[] cbuf, int off, int len) 写入字符数组的一部分

void write(String str) 写一个字符串

void write(String str, int off, int len) 写一个字符串的一部分

flush() 刷新流,可以继续写数据

close() 关闭流,释放资源,但是在关闭之前会先刷新流;

一旦关闭,就不能再写数据

e5cec3f86ea14d9d77c798a0f48dc44.png

import java.io.*;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        int read = 0;
        //创建一个读入数据的相对路径的流
        FileReader fileReader = new FileReader("data/access.log");
        FileWriter fileWriter = new FileWriter("data/access1.log");
        //直接读取字符输出
        while((read = fileReader.read()) != -1){
            fileWriter.write(read);
        }
        //根据数组存储要求输出
        char[] ch = new char[8];
        while ((read = fileReader.read(ch)) != -1) {
            fileWriter.write(new String(ch, 0, read));
        }
        System.out.println("复制OK");
        fileWriter.flush();
        //关闭读入流
        fileReader.close();
        //关闭写出
        fileWriter.close();
    }
}

场景

字节流适合做文件数据的拷贝(音视频,文本)

字节流不适合读取中文内容输出

字符流适合做文本文件的操作(读,写)

二、缓冲流

1、概念

缓冲流是高效流或者高级流,前面学习的字节流算原始流

作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写性能

2、优化原理

字节缓冲输入流默认有8KB缓冲池,直接从缓冲池读取数据,性能较好。

字节缓冲输入流默认有8KB缓冲池,数据直接写入缓冲池中,提高写数据性能

3、体系图

057d718153d634179bb7c0031bbc2a2.png

4、字节缓冲流

1)BufferedInputStream字节缓冲输入流

提高字节输入流读取数据的性能

2)BufferedOutputStream字节缓存输出流

提高字节输出流读取数据的性能

构造器 解释

public BufferedInputStream(InputStream is) 创建一个新的缓冲输入流

public BufferedOutputStream(OutputStream os) 创建一个新的缓冲输出流

9f87b09fd307e10d4e5ad3ecfc57157.png

import java.io.*;
import java.nio.charset.StandardCharsets;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        int read = 0;
        //创建一个读入数据的相对路径的流
        InputStream inputStream = new FileInputStream("data/access.log");
        //创建带有缓存的输入流
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        //创建一个数组
        byte[] by = new byte[1024];
        //判断是否还有数据
        while ((read = bis.read(by)) != -1) {
            //转换字符串
            String str = new String(by, 0, read);
            System.out.println(str);
        }
        //关闭写出
        bis.close();
        //关闭读入流
        inputStream.close();
        //创建一个输出数据的相对路径的流
        OutputStream outputStream = new FileOutputStream("data/access1.log");
        //创建带有缓存的输出流
        BufferedOutputStream bos = new BufferedOutputStream(outputStream);
        //直接写入内容,设置编码格式
        bos.write("helloworld".getBytes(StandardCharsets.UTF_8));
        bos.close();
        outputStream.close();
    }
}

5、字符缓冲流

1)BufferedReader字符缓冲输入流

提高字符输入流读取数据的性能,可以按行读取数据

构造器 解释

public BufferedReader(Reader r) 创建一个新的字符缓冲输入流

方法 解释

public String readLine() 读取一行数据,没有数据返回null

2)BufferedWriter字符缓冲输出流

提高字符输出流写取数据的性能,可以换行

构造器 解释

public BufferedWriter(Writer w) 写入一行数据

方法 解释

public void newLine() 换行

f33fffe4177def8d8c0842e156e4fd2.png

import java.io.*;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        String msg = null;
        //创建一个字符输入流
        FileReader fr = new FileReader("data/access.log");
        //创建一个字符输入缓冲流
        BufferedReader br = new BufferedReader(fr);
        //判断是不是最后一行
        while ((msg = br.readLine()) != null) {
            System.out.println(msg);
        }
        //关闭输入缓冲流
        br.close();
        //创建一个字符输出流
        FileWriter fw = new FileWriter("data/access1.log");
        //创建一个字符输出缓冲流
        BufferedWriter bw = new BufferedWriter(fw);
        //字符写入的内容
        bw.write("china");
        //关闭字符缓冲流
        bw.close();
    }
}

三、转换流

文件和代码编码不一致,会出现乱码

1、InputStreamReader字符输入转换流

把原始的字节流按照指定编码转换成字符输入流

构造器 解释

public InputStreamReader(InputStream is) 字节流按照代码默认编码转换成字符输入流

public InputStreamReader(InputStream is ,String charset) 原始的字节流按照指定编码转换成字符输入流,不会出现乱码

1321866213d922c9b19181a0d2fd611.png

import java.io.*;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        int len = 0;
        //创建一个InputStreamReader对象,FileInputStream构造一个原始的字节流按照指定编码转换成字符输入流
        InputStreamReader gbk = new InputStreamReader(new FileInputStream("data/access1.log"),"GBK");
        //判断是不是最后一行
        while ((len = gbk.read()) != -1) {
            System.out.print((char)len);
        }
        System.out.println();
        //释放资源
        gbk.close();
        InputStreamReader utf = new InputStreamReader(new FileInputStream("data/access1.log"),"utf8");
        while ((len = utf.read()) != -1) {
            System.out.print((char)len);
        }
        utf.close();
    }
}

2、OutputStreamWriter字符输出转换流

把字节输出流按照指定编码转换成字符输出流

构造器 解释

public OutputStreamWriter(OutputStream os) 原始的字节输出流按照代码默认编码转换成字符输出流

public OutputStreamWriter(OutputStream os,String charset) 原始的字节输出流按照指定编码转换成字符输出流,不会出现乱码

0103df09f6d32fe28322aeedf4dfac0.png

import java.io.*;
public class ClassStructure {
    public static void main(String[] args) throws IOException {
        //字节输出流指定编码格式
        OutputStreamWriter gbk = new OutputStreamWriter(new FileOutputStream("data/access1.log"), "GBK");
        //写入内容
        gbk.write("china,我爱你!!!");
        //释放资源
        gbk.close();
        OutputStreamWriter gbk1 = new OutputStreamWriter(new FileOutputStream("data/access2.log"), "utf-8");
        gbk1.write("china,我爱你!!!");
        gbk1.close();
    }
}


相关文章
|
1天前
|
Java
"揭秘Java IO三大模式:BIO、NIO、AIO背后的秘密!为何AIO成为高并发时代的宠儿,你的选择对了吗?"
【8月更文挑战第19天】在Java的IO编程中,BIO、NIO与AIO代表了三种不同的IO处理机制。BIO采用同步阻塞模型,每个连接需单独线程处理,适用于连接少且稳定的场景。NIO引入了非阻塞性质,利用Channel、Buffer与Selector实现多路复用,提升了效率与吞吐量。AIO则是真正的异步IO,在JDK 7中引入,通过回调或Future机制在IO操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
|
7天前
|
Java Android开发
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
26 1
|
12天前
|
存储 缓存 Java
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
35 3
|
20天前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
|
25天前
|
Java Perl
Java进阶之正则表达式
【7月更文挑战第17天】正则表达式(RegEx)是一种模式匹配工具,用于在字符串中执行搜索、替换等操作。它由普通字符和特殊元字符组成,后者定义匹配规则。
17 4
|
28天前
|
设计模式 Java
Java进阶之代理
Java进阶之代理
18 4
|
28天前
|
设计模式 Java
Java进阶之代理
Java进阶之代理
17 3
|
28天前
|
设计模式 Java
Java进阶之代理
【7月更文挑战第16天】Java动态代理通过`java.lang.reflect.Proxy`和`InvocationHandler`实现,无需编译期定义代理类。与静态代理相比,它更灵活,代码更简洁,适用于方法数量变化或未知接口代理。
17 2
|
29天前
|
Java 编译器 API
Java进阶之标准注解
【7月更文挑战第15天】Java标准注解包括标记注解(如@Deprecated)、@Override(检查方法重写)、@SuppressWarnings(抑制警告)。多值注解如@RequestMapping在Spring中用于HTTP请求映射。元注解如@Retention控制注解保留策略,@Target指定应用位置。Java8引入类型注解(@FunctionalInterface、@SafeVarargs)和重复注解(@Repeatable)。自定义注解可通过反射读取,如示例中的MyMarkerAnnotation等。
17 2
|
1月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
26 6