Java IO流(下)

简介: 字符流、缓冲流 转换流 序列化 IO框架等 打印流

1、字符流


字节流读取中文输出会存在什么问题?


  • 会乱码。或者内存溢出。


读取中文输出,哪个流更合适,为什么?


  • 字符流更合适,最小单位是按照单个字符读取的。


(1)文件字符输入流:FileReader

作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去

image.png



(2)文件字符输出流:FileWriter

作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去的流。

image.png


文件字符输出流(FileWriter)写数据出去的API:

image.png



流的关闭与刷新:

image.png


字节流、字符流的使用场景总结?


  • 字节流适合做一切文件数据的拷贝(音视频,文本)
  • 字节流不适合读取中文内容输出
  • 字符流适合做文本文件的操作(读,写)


2、缓冲流


(1)概述

  • 缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
  • 作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。


缓冲流种类


  • 字节缓冲输入流: BufferedInputStream
  • 字节缓冲输出流:BufferedOutputStream
  • 字符缓冲输入流:BufferedReader
  • 字符缓冲输出流:BufferedWriter


(2)字节缓冲流

字节缓冲流性能优化原理:


  • 字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
  • 字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。


字节缓冲流


  • 字节缓冲输入流:BufferedInputStream,提高字节输入流读取数据的性能。
  • 字节缓冲输出流:BufferedOutputStream,提高字节输出流读取数据的性能。


示例:


import java.io.*;
public class Test7 {
    public static void main(String[] args){
        try {
            InputStream is=new FileInputStream("C:\\Users\\Eastward\\Pictures\\素材:时光清浅  水下嫣然\\低版本水下.jpg");
            InputStream bis=new BufferedInputStream(is);
            OutputStream os=new FileOutputStream("C:\\Users\\Eastward\\Pictures\\素材1.jpg");
            OutputStream bos=new BufferedOutputStream(os);
            byte[] buffer=new byte[1024];
            int len;
            while((len=is.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
            System.out.println("复制完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


(3)字符缓冲流

字符缓冲输入流:BufferedReader ,提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能

image.png



字符缓冲输出流:BufferedWriter,提高字符输出流写取数据的性能,除此之外多了换行功能

image.png




案例: 拷贝出师表到另一个文件,恢复顺序


需求:把《出师表》的文章顺序进行恢复到一个新文件中。


分析: ① 定义一个缓存字符输入流管道与源文件接通。

② 定义一个List集合存储读取的每行数据。

③ 定义一个循环按照行读取数据,存入到List集合中去。

④ 对List集合中的每行数据按照首字符编号升序排序。

⑤ 定义一个缓存字符输出管道与目标文件接通。

⑥ 遍历List集合中的每个元素,用缓冲输出管道写出并换行。


代码:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;
public class Test8 {
    public static void main(String[] args){
        try(
                BufferedReader br = new BufferedReader(
                        new FileReader("C:\\Users\\Eastward\\Desktop\\Java\\假期练习2022.7\\Exercises12\\src\\test"));
                BufferedWriter bw = new BufferedWriter(
                        new FileWriter("C:\\Users\\Eastward\\Desktop\\Java\\假期练习2022.7\\Exercises12\\src\\newTest"));
                ){
            List<String> data=new ArrayList<>();
            String line;
            while((line= br.readLine())!=null){
                data.add(line);
            }
            System.out.println("原文件:"+data);
            //自定义排序规则
            List<String> sizes=new ArrayList<>();
            Collections.addAll(sizes,"1","2","3");
            Collections.sort(data,new Comparator<String>(){
                public int compare(String o1,String o2){
                    return sizes.indexOf(o1.substring(0,o1.indexOf(".")))
                            -sizes.indexOf(o2.substring(0,o2.indexOf(".")));
                }
            });
            System.out.println("排序后:"+data);
            for(String data1:data){
                bw.write(data1);
                bw.newLine();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}


示例:


原文件:[1.第一行, 3.第三行, 2.第二行]

排序后:[1.第一行, 2.第二行, 3.第三行]


3、转换流


image.png


(1)字符输入转换流

字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。

image.png


字符输入转换流InputStreamReader作用:


可以解决字符流读取不同编码乱码的问题

public InputStreamReader(InputStream is,String charset): 可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。

(2)字符输出转换流

字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。

image.png


字符输出转换流OutputStreamWriter的作用?


public OutputStreamWriter(OutputStream os,String charset)

可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!


4、序列化对象


image.png


(1)对象序列化

使用到的流是对象字节输出流:ObjectOutputStream

作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化。

image.png

ObjectOutputStream序列化方法

image.png



(2)对象反序列化

使用到的流是对象字节输入流:ObjectInputStream

作用:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。

image.png

ObjectInputStream序列化方法

image.png



5、打印流


作用:打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指:PrintStream,PrintWriter两个类。

可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。

(1)PrintStream、PrintWriter

PrintStream

image.png

PrintWriter

image.png

PrintStream和PrintWriter的区别


  • 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
  • PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
  • PrintWriter继承自字符输出流Writer,支持写字符数据出去

(2)输出语句的重定向

属于打印流的一种应用,可以把输出语句的打印位置改到文件。

PrintStream ps = new PrintStream("文件地址") System.setOut(ps);

示例:


import java.io.PrintStream;
import java.io.PrintWriter;
/**
 * 目标:改变输出语句的位置到文件(输出语句重定向)
 */
public class PrintDemo2 {
    public static void main(String[] args) throws Exception {
        System.out.println("锦瑟无端五十弦");
        System.out.println("一弦一柱思华年");
        //改变输出语句的位置(重定向)
        PrintStream ps=new PrintStream("oi-app2/src/log.txt");
        System.setOut(ps);//把系统打印流改成自己的打印流
        System.out.println("庄生晓梦迷蝴蝶");
        System.out.println("望帝春心托杜鹃");
    }
}


6、补充知识


(1)Properties

image.png

Properties属性集对象


  • 其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。


Properties核心作用:

  • Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
  • 属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。


Properties的API:

  • Properties和IO流结合的方法:

image.png


总结



Properties的作用?


  • 可以存储Properties属性集的键值对数据到属性文件中去: void store(Writer writer, String comments)
  • 可以加载属性文件中的数据到Properties对象中来: void load(Reader reader)

(2)IO框架

commons-io概述


  • commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
  • commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils

FileUtils主要有如下方法:

image.png


导入commons-io-2.6.jar做开发


需求:使用commons-io简化io流读写


分析:① 在项目中创建一个文件夹:lib

② 将commons-io-2.6.jar文件复制到lib文件夹

③ 在jar文件上点右键,选择 Add as Library -> 点击OK

④ 在类中导包使用


目标:Commons-io包的使用介绍。


什么是Commons-io包?
        commons-io是apache开源基金组织提供的一组有关IO操作的类库,
        可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类,
见下表:
     | 包                                  | 功能描述                                     |
     | ----------------------------------- | :------------------------------------------- |
     | org.apache.commons.io               | 有关Streams、Readers、Writers、Files的工具类 |
     | org.apache.commons.io.input         | 输入流相关的实现类,包含Reader和InputStream  |
     | org.apache.commons.io.output        | 输出流相关的实现类,包含Writer和OutputStream |
     | org.apache.commons.io.serialization | 序列化相关的类
步骤:
     1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
     2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
     3. 将commons-io-2.6.jar加入到classpath中
小结:
     IOUtils和FileUtils可以方便的复制文件和文件夹!!


代码:


import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CommonsIODemo01 {
    public static void main(String[] args) throws Exception {
       // 1.完成文件复制!
       // IOUtils.copy(new FileInputStream("C:\\Users\\zhao\\Pictures\\微信图片_20220429140831.jpg"),new FileOutputStream("D:\\Temp\\new.jpg"));
        // 2.完成文件复制到某个文件夹下!
        FileUtils.copyFileToDirectory(new File("C:\\Users\\zhao\\Pictures\\微信图片_20220429140831.jpg"),new File("D:/"));
        //3.完成文件夹复制到文件夹
        FileUtils.copyDirectoryToDirectory(new File("D:/Temp/aaa"), new File("D:/Temp/ccc"));
        //删掉
        FileUtils.deleteDirectory(new File("D:/Temp/ccc/aaa"));
    }
}
目录
相关文章
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
446 0
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
446 1
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
324 3
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
784 23
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
643 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
437 10
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)