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"));
    }
}
目录
相关文章
|
30天前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
6天前
|
安全 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版)
|
16天前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
29天前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
25 2
|
30天前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
30天前
|
缓存 Java
【IO面试题 一】、介绍一下Java中的IO流
Java中的IO流是对数据输入输出操作的抽象,分为输入流和输出流,字节流和字符流,节点流和处理流,提供了多种类支持不同数据源和操作,如文件流、数组流、管道流、字符串流、缓冲流、转换流、对象流、打印流、推回输入流和数据流等。
【IO面试题 一】、介绍一下Java中的IO流
|
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操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
28 2
|
1月前
|
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
95 1
|
1月前
|
存储 缓存 Java
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
42 3