JAVA基础 IO流技术学习笔记 3

简介: JAVA基础 IO流技术学习笔记

8.3.3 字符输出流

package cn.it.bz.IO;
import java.io.IOException;
import java.io.PrintWriter;
public class TestPrintWriter {
    public static void main(String[] args) {
        //创建字符流输出对象
        try(PrintWriter printWriter = new PrintWriter("D:/a.txt")) {
            printWriter.print("Java");//不换行
            printWriter.print("百战");
            printWriter.println("sxt");//换行
            printWriter.println("哈哈哈");
            printWriter.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

小练习:通过字符输出流添加行号

package cn.it.bz.IO;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class TestLineNumber3 {
    public static void main(String[] args) {
        try(
                //读入一行数据数据
                BufferedReader bufferedReader = new BufferedReader(new FileReader("D:/a.txt"));
                //输出数据
                PrintWriter printWriter = new PrintWriter("D:/a1.txt")) {
            int i = 1;
            String s = "";
            while ((s = bufferedReader.readLine()) != null){
                printWriter.println(i+"、"+s);
                i++;
            }
            //释放资源
            printWriter.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

8.4  数据流

数据流将“基本数据类型与字符串类型”作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。数据流是处理流,不是节点流,而且只能处理文件字节流,不能处理文件字符流。

package cn.it.bz.IO;
import com.sun.org.apache.xerces.internal.impl.dv.dtd.IDREFDatatypeValidator;
import java.io.*;
public class TestDataOutputStream {
    public static void main(String[] args) {
        //先向文件写数据,在从文件获取数据。
        try(DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("D:/a.txt"));
            DataInputStream dataInputStream = new DataInputStream(new FileInputStream("d:/a.txt"))
        ) {
            //将如下数据写到文件
            dataOutputStream.writeChar('张');
            dataOutputStream.writeUTF("输出字符串");
            dataOutputStream.writeInt(123);
            dataOutputStream.writeDouble(Math.random());
            dataOutputStream.writeBoolean(true);
            dataOutputStream.flush();
            //读取顺序需要和写入顺序一样才行
            System.out.println(dataInputStream.readChar());
            System.out.println(dataInputStream.readUTF());
            System.out.println(dataInputStream.readInt());
            System.out.println(dataInputStream.readDouble());
            System.out.println(dataInputStream.readBoolean());
        }catch (IOException E){
            E.printStackTrace();
        }
    }
}

1、使用数据流时,读取的顺序一定要与写入的顺序一致,否则不能正确读取数据。

2、数据流只能处理文件字节流,不能处理文件字符流

8.5 对象流

我们前边学到的数据流只能实现对基本数据类型和字符串类型的读写,并不能读取对象(字符串除外),如果要对某个对象进行读写操作,我们需要学习一对新的处理流:

ObjectInputStream/ObjectOutputStream。对象流实际上是数据流的升级版,使用对象流也能实现对Java中基本数据类型的读写操作,还能对自定义对象进行读写操作。对象流和数据流一样都是处理流,只能处理字节流不能处理字符流。

8.5.1 对象流处理基本数据类型

package cn.it.bz.IO;
import java.io.*;
public class TestObjectStreamBasicType {
    public static void main(String[] args) {
        try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/a.txt"));
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:/a.txt"))
        ) {
            //数据写出
            objectOutputStream.writeInt(123);
            objectOutputStream.writeChar('h');
            objectOutputStream.writeBoolean(true);
            //刷新
            objectOutputStream.flush();
            //按照写入的顺序读取数据
            System.out.println(objectInputStream.readInt());
            System.out.println(objectInputStream.readChar());
            System.out.println(objectInputStream.readBoolean());
        }catch (IOException E){
           E.printStackTrace();
        }
    }
}

8.5.2 对象流将对象序列化到文件

ObjectOutputStream可以将一个内存中的Java对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序列化接口,否则会抛出异常。

package cn.it.bz.IO;
import java.io.*;
public class TestObjectOutputStream {
    public static void main(String[] args) {
        try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/a.txt"));
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:/a.txt"))) {
            //创建Users对象
            Users users = new Users(123,"zhangsan","12");
            //将对象序列化到文件
            objectOutputStream.writeObject(users);
            //刷新
            objectOutputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

如果想一次性将多个对象序列化到文件中,可以将对象放在集合中,集合实现了序列化接口。

8.5.3 将对象反序列化到内存中

package cn.it.bz.IO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class TestObjectInputStream {
    public static void main(String[] args) {
        //创建对象输入字节流与文件字节输入流对象
        try(ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:/a.txt"))){
            //将对象反序列化到内存中
            Users users = (Users) objectInputStream.readObject();
            System.out.println(users);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

九、File类在IO中的作用

File是操作文件的,当以文件作为数据源或目标时,除了可以使用字符串作为文件以及位置的指定以外,我们也可以使用File类指定。

package cn.it.bz.IO;
import java.io.*;
public class TestFile {
    public static void main(String[] args) {
        try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:/a.txt")),"gbk"))) {
            String s ="";
            while ((s = bufferedReader.readLine()) != null){
                System.out.println(s);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

十、装饰器模式构建IO流体系

10.1 装饰器模式简介

装饰器模式是GOF23种设计模式中较为常用的一种模式。它可以实现对原有类的包装和装饰,使新的类具有更强的功能。

package cn.it.bz.IO;
class Iphone{
    private String name;
    public Iphone(String name) {
        this.name = name;
    }
    public void show() {
        System.out.println("我是" + name + ",可以在屏幕上显示");
    }
}
//装饰器
class TouyingPhone {
    public Iphone phone;
    public TouyingPhone(Iphone p) {
        this.phone = p;
    }
    // 对Iphone功能的扩展
    public void show() {
        phone.show();
        System.out.println("还可以投影,在墙壁上显示");
    }
}
public class TestDecoration {
    public static void main(String[] args) {
        Iphone iphone = new Iphone("苹果18");
        //将有投影能力的手机壳装到手机上
        TouyingPhone touyingPhone = new TouyingPhone(iphone);
        touyingPhone.show();
    }
}

10.2 IO流体系中的装饰器模式

IO流体系中大量使用了装饰器模式,让流具有更强的功能、更强的灵活性。比如:


FileInputStream fis = new FileInputStream(src);

BufferedInputStream bis = new BufferedInputStream(fis);显然BufferedInputStream装饰了原有的FileInputStream,让普通的FileInputStream也具备了缓存功能,提高了效率。

十一、Apache IO包

Apache基金会介绍

Apache软件基金会(也就是Apache Software Foundation,简称为ASF),是专门为支持开源软件项目而办的一个非盈利性组织。在它所支持的Apache项目与子项目中,所发行的软件产品都遵循Apache许可证(Apache License)。 官方网址为:www.apache.org


很多著名的Java开源项目都来源于这个组织。比如:commons、kafka、lucene、maven、shiro、struts等技术,以及大数据技术中的:hadoop(大数据第一技术)、hbase、spark、storm、mahout等。


commons-io工具包


Apache的commons-io工具包中提供了IOUtils/FileUtils,为我们提供了更加简单、功能更加强大的文件操作和IO流操作功能。


下载与添加commons-io包


下载地址


Commons IO – Download Apache Commons IO


在项目中创建lib文件境jar包拖入到该文件中,然后右键lib选择Add as Library

11.1  FileUtils类中常用方法的介绍

打开FileUtils的api文档,我们抽出一些工作中比较常用的静态方法,进行总结和讲解。总结如下:

方法名 使用说明
cleanDirectory 清空目录,但不删除目录
contentEquals 比较两个文件的内容是否相同
copyDirectory 将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的文件
copyFile 将一个文件拷贝到一个新的地址
copyFileToDirectory 将一个文件拷贝到某个目录下
copyInputStreamToFile 将一个输入流中的内容拷贝到某个文件
deleteDirectory 删除目录
deleteQuietly 删除文件
listFiles 列出指定目录下的所有文件
openInputSteam 打开指定文件的输入流
readFileToString 将文件内容作为字符串返回
readLines 将文件内容按行返回到一个字符串数组中
size 返回文件或目录的大小
write 将字符串内容直接写到文件中
writeByteArrayToFile 将字节数组内容写到文件中
writeLines 将容器中的元素的toString方法返回的内容依次写入文件中
writeStringToFile 将字符串内容写到文件中

11.1.1使用FileUtils工具类读取文件

package cn.it.bz.IO;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class TestUtils1 {
    public static void main(String[] args) throws IOException {
        //content表示读取的文件中的全部的内容
        String content = FileUtils.readFileToString(new File("D:/a.txt"), "gbk");
        System.out.println(content);
    }
}

11.1.2使用FileUtils工具类实现目录拷贝

我们可以使用FileUtils完成目录拷贝,在拷贝过程中可以通过文件过滤器(FileFilter)选择拷贝内容。

package cn.it.bz.IO;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class TestFileUtils2 {
    public static void main(String[] args) throws IOException {
        FileUtils.copyDirectory(new File("D:\\图片"), new File("d:/aaa"), new FileFilter() {
            //给定文件拷贝规则,只拷贝以png结尾的文件
                    @Override
                    public boolean accept(File pathname) {
                         if (pathname.getName().endsWith(".png")){
                             return true;  //拷贝
                         }
                        return false;  //不拷贝
                    }
                }
        );
    }
}

11.2 IOUtils的妙用

打开IOUtils的api文档,我们发现它的方法大部分都是重载的。所以,我们理解它的方法并不是难事。因此,对于方法的用法总结如下:

方法名 使用说明
buffer 将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小
closeQueitly 关闭流
contentEquals 比较两个流中的内容是否一致
copy 将输入流中的内容拷贝到输出流中,并可以指定字符编码
copyLarge 将输入流中的内容拷贝到输出流中,适合大于2G内容的拷贝
lineIterator 返回可以迭代每一行内容的迭代器
read 将输入流中的部分内容读入到字节数组中
readFully 将输入流中的所有内容读入到字节数组中
readLine 读入输入流内容中的一行
toBufferedInputStream,toBufferedReader 将输入转为带缓存的输入流
toByteArray,toCharArray 将输入流的内容转为字节数组、字符数组
toString 将输入流或数组中的内容转化为字符串
write 向流里面写入内容
writeLine 向流里面写入一行内容
package cn.it.bz.IO;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestIOUtilsDemo {
    public static void main(String[] args) throws IOException {
        String content = IOUtils.toString(new FileInputStream("D:/a.txt"), "gbk");
        System.out.println(content);
    }
}

实际上就是相当于文件字节输入流套上了文件字符转换流(并指定解码规则)再套上文件字符缓冲流。

相关文章
|
5月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
676 44
|
5月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
609 1
|
6月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
213 4
|
4月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
237 1
|
5月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
5月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
6月前
|
Java 测试技术 API
2025 年 Java 开发者必知的最新技术实操指南全览
本指南涵盖Java 21+核心实操,详解虚拟线程、Spring Boot 3.3+GraalVM、Jakarta EE 10+MicroProfile 6微服务开发,并提供现代Java开发最佳实践,助力开发者高效构建高性能应用。
1000 4
|
6月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
5月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
475 0
java202302java学习笔记第七天-n种内部类
java202302java学习笔记第七天-n种内部类
140 0
java202302java学习笔记第七天-n种内部类