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"));
    }
}
目录
相关文章
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
67 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
安全 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版)
|
1月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
35 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
76 1
|
29天前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
46 0
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
35 0
|
2月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
3月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
46 2