• 深入理解Java IO流(第二篇)


     ✅作者简介:大家好我是@每天都要敲代码,一位材料转码农的选手,希望一起努力,一起进步!
    📃个人主页:@每天都要敲代码的个人主页

     🔥系列专栏:JavaSE从入门到精通
    💬推荐一款模拟面试、刷题神器,从基础到大厂面试题👉点击跳转刷题网站进行注册学习

    目录

    🥅缓冲流

    1.字符输入流BufferedReader

    2.字符输出流BufferedWriter

    🥅转换流

    1.OutputStreamWriter

    2.InputStreamReader

    🥅数据流

    1.DataOutputStream

    2.DataInputStream

    🥅标准输出流

    1.PrintStream

    2.日志工具类

    🥅File类的理解

    1.常用方法1

    2.常用方法2

    3.listFiles方法

    结束语


    🥅缓冲流

    (1)带有缓冲区的字符输入流;使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组;自带缓冲!

    (2)读取数据时,可以一次性读取一行

    (3)这里只讲解字符缓冲流: java.io.BufferedReader 和 java.io.BufferedWriter;字节缓冲流使用方法是一样的

    (4)BufferedReader和BufferedWriter都是包装流!

    1.字符输入流BufferedReader

    1. package com.bjpowernode.java.io;
    2. import java.io.BufferedReader;
    3. import java.io.FileNotFoundException;
    4. import java.io.FileReader;
    5. public class BufferedReaderTest01 {
    6. public static void main(String[] args) throws Exception {
    7. FileReader reader = new FileReader("file");
    8. // 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
    9. // 外部负责包装的这个流,叫做:包装流或者叫做:处理流。
    10. // FileReader就是一个节点流。BufferedReader就是包装流/处理流。
    11. BufferedReader br = new BufferedReader(reader); // 只能传字符流
    12. // 优点:一次能读一行;但不带换行符!
    13. String s = null;
    14. while((s = br.readLine()) != null){ // br.readLine()返回的是一个字符串
    15. System.out.println(s);
    16. }
    17. // 关闭流,只需要关闭最外层流就行,里面的节点流会自动关闭。
    18. br.close();
    19. }
    20. }

    2.字符输出流BufferedWriter

    1. package com.bjpowernode.java.io;
    2. import java.io.*;
    3. public class BufferedWriterTest01 {
    4. public static void main(String[] args) throws IOException {
    5. // 创建带有缓冲区的字符输出流
    6. BufferedWriter writer = new BufferedWriter(new FileWriter("file"));
    7. // 开始写
    8. writer.write("hello world!");
    9. writer.write("\n");
    10. writer.write("hello kitty!");
    11. // 刷新
    12. writer.flush();
    13. // 关闭最外层
    14. writer.close();
    15. }
    16. }

    🥅转换流

    1.OutputStreamWriter

    BufferedWriter:带有缓冲的字符输出流。

    OutputStreamWriter:转换流

    1. package com.bjpowernode.java.io;
    2. import java.io.*;
    3. public class BufferedWriterTest01 {
    4. public static void main(String[] args) throws IOException {
    5. // 创建带有缓冲区的字符输出流
    6. BufferedWriter writer = new BufferedWriter(new FileWriter("file"));
    7. // 如果想要使用字节输出流,还是需要OutputStreamWriter进行流的转换
    8. // 如果使用的是字节流
    9. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file"));
    10. BufferedWriter writer1 = new BufferedWriter(osw);
    11. // 合并在一起
    12. BufferedWriter writer1 = new BufferedWriter(new OutputStreamWriter
    13. (new FileOutputStream("file")));
    14. // 开始写
    15. writer.write("hello world!");
    16. writer.write("\n");
    17. writer.write("hello kitty!");
    18. // 刷新
    19. writer.flush();
    20. // 关闭最外层
    21. writer.close();
    22. }
    23. }

    2.InputStreamReader

    BufferedReader(reader),里面只能传字符流;那如果是字节流怎么办呢?

    需要使用转换流:InputStreamReader,把将字节流转换成字符流
    1. package com.bjpowernode.java.io;
    2. import java.io.*;
    3. public class BufferedReaderTest02 {
    4. public static void main(String[] args) {
    5. FileInputStream fis = null;
    6. try {
    7. // 字节流
    8. fis = new FileInputStream("file");
    9. // 通过转换流转换(InputStreamReader将字节流转换成字符流)
    10. // fis是节点流。reader是包装流。
    11. InputStreamReader reader = new InputStreamReader(fis);
    12. // 把转换成字符流的字节流,传过来
    13. // reader是节点流。br是包装流。
    14. BufferedReader br = new BufferedReader(reader);
    15. // 上面进行合并
    16. BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("file")));
    17. // 进行打印
    18. String s = null;
    19. while((s = br1.readLine()) != null){
    20. System.out.println(s);
    21. }
    22. // 关闭
    23. br.close(); // 关闭最外层
    24. } catch (FileNotFoundException e) {
    25. e.printStackTrace();
    26. } catch (IOException e) {
    27. e.printStackTrace();
    28. } finally {
    29. if (fis != null) {
    30. try {
    31. fis.close();
    32. } catch (IOException e) {
    33. e.printStackTrace();
    34. }
    35. }
    36. }
    37. }
    38. }

    🥅数据流

    1.DataOutputStream

    (1)java.io.DataOutputStream:数据专属的流;也是一个包装流!
    (2)这个流可以将数据连同数据的类型一并写入文件
    (3)注意:这个文件不是普通文本文档。(这个文件使用记事本打不开)

    1. package com.bjpowernode.java.io;
    2. import java.io.DataOutputStream;
    3. import java.io.FileOutputStream;
    4. public class DataOutputStreamTest01 {
    5. public static void main(String[] args) throws Exception{
    6. // 创建数据专属的字节输出流(写)
    7. DataOutputStream dos = new DataOutputStream(new FileOutputStream("file")); //生成的这个文件,记事本打不开
    8. // 写数据
    9. byte b = 100;
    10. short s = 200;
    11. int i = 300;
    12. long l = 400L;
    13. float f = 3.0F;
    14. double d = 3.14;
    15. boolean sex = false;
    16. char c = 'a';
    17. // 写;把数据以及数据的类型一并写入到文件当中
    18. dos.writeByte(b);
    19. dos.writeShort(s);
    20. dos.writeInt(i);
    21. dos.writeLong(l);
    22. dos.writeFloat(f);
    23. dos.writeDouble(d);
    24. dos.writeBoolean(sex);
    25. dos.writeChar(c);
    26. // 刷新
    27. dos.flush();
    28. // 关闭最外层
    29. dos.close();
    30. }
    31. }

    2.DataInputStream

    (1)DataInputStream:数据字节输入流。
    (2)DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序;读的顺序需要和写的顺序一致。才可以正常取出数据

    1. package com.bjpowernode.java.io;
    2. import java.io.DataInputStream;
    3. import java.io.FileInputStream;
    4. public class DataInputStreamTest01 {
    5. public static void main(String[] args) throws Exception {
    6. // 创建数据专属的字节输入流(读)
    7. DataInputStream dis = new DataInputStream(new FileInputStream("file"));
    8. // 开始读
    9. byte b = dis.readByte();
    10. short s = dis.readShort();
    11. int i = dis.readInt();
    12. long l = dis.readLong();
    13. float f = dis.readFloat();
    14. double d = dis.readDouble();
    15. boolean sex = dis.readBoolean();
    16. char c = dis.readChar();
    17. // 打印
    18. System.out.println(b);
    19. System.out.println(s);
    20. System.out.println(i);
    21. System.out.println(l);
    22. System.out.println(f);
    23. System.out.println(d);
    24. System.out.println(sex);
    25. System.out.println(c);
    26. // 关闭流
    27. dis.close();
    28. }
    29. }

    🥅标准输出流

    1.PrintStream

    (1)jva.io.PrintStream:标准的字节输出流。默认输出到控制台。
    (2)标准输出流不需要手动close()关闭

    (3)可以通过System.setOut()方法改变输出流的方向

    1. package com.bjpowernode.java.io;
    2. import java.io.FileOutputStream;
    3. import java.io.PrintStream;
    4. public class PrintStreamTest {
    5. public static void main(String[] args) throws Exception {
    6. System.out.println("hello world");
    7. // 实际上上述代码可以拆分成
    8. PrintStream ps = System.out;
    9. ps.println("hello world");
    10. // 可以改变标准输出流的输出方向;
    11. // 例如:标准输出流不在指向控制台,指向log文件
    12. PrintStream printStream = new PrintStream(new FileOutputStream("log"));
    13. // 修改输出方向
    14. System.setOut(printStream);
    15. // 输出
    16. System.out.println("Hello World"); //不会再输出到控制台,而是到log文件
    17. }
    18. }

    2.日志工具类

    那么标准输出流PrintStream有什么用呢?我们不妨写一个简单的日志工具类!

    日志框架

    1. package com.bjpowernode.java.io;
    2. import java.io.FileNotFoundException;
    3. import java.io.FileOutputStream;
    4. import java.io.PrintStream;
    5. import java.text.SimpleDateFormat;
    6. import java.util.Date;
    7. // 日志工具
    8. public class Logger {
    9. // 记录日志的方法
    10. public static void log(String msg) {
    11. try {
    12. PrintStream out = new PrintStream(new FileOutputStream("log.txt",true));
    13. // 改变流的方向
    14. System.setOut(out);
    15. // 获取系统当前时间
    16. Date nowDate = new Date();
    17. // 格式类型转换
    18. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
    19. String myNowdate = sdf.format(nowDate);
    20. // 打印
    21. System.out.println(myNowdate+":"+msg);
    22. } catch (FileNotFoundException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }

    日志测试

    1. package com.bjpowernode.java.io;
    2. public class LoggerTest {
    3. public static void main(String[] args) {
    4. // 测试日志工具类
    5. Logger.log("调用了System类的gc()方法,建议启动垃圾回收");
    6. Logger.log("调用了UserService的doSome()方法");
    7. Logger.log("用户尝试进行登录,验证失败");
    8. // 在log.txt打印的结果
    9. /* 2022-07-22 08:47:49 667:调用了System类的gc()方法,建议启动垃圾回收
    10. 2022-07-22 08:47:49 703:调用了UserService的doSome()方法
    11. 2022-07-22 08:47:49 714:用户尝试进行登录,验证失败*/
    12. }
    13. }

    🥅File类的理解

    java.io.File
        1、File类和四大家族没有关系,所以File类不能完成文件的读和写。
        2、File对象代表什么?
            文件和目录路径名的抽象表示形式。
            C:\Drivers 这是一个File对象
            C:\Drivers\Lan\Realtek\Readme.txt 也是File对象。
            一个File对象有可能对应的是目录,也可能是文件;File只是一个路径名的抽象表示形式;不能通过File完成文件的读和写

    1.常用方法1

    (1)exists()方法:判断当前文件是否存在

    (2)creatNewFile()方法:以文件的形式创建出来

    (3)mkdir()方法:以目录的形式创建出来;创建多重目录mkdirs()方法

    (4)获取当前文件的父路径

            方法1: 使用getParent(),返回的是一个String
            方法2:使用getParentFile(),返回的是一个File;和上面效果是一样的

    (5)getAbsolutePath()方法:获取当前文件的绝对路径

    1. package com.bjpowernode.java.io;
    2. import java.io.File;
    3. public class FileTest01 {
    4. public static void main(String[] args) throws Exception {
    5. // 创建File对象
    6. File f1 = new File("D:\\file");
    7. // 1、判断当前文件是否存在;exists()方法
    8. System.out.println(f1.exists()); // false
    9. // 2、如果D:\file不存在,则以文件的形式创建出来;createNewFile()方法
    10. if (!f1.exists()) {
    11. f1.createNewFile();
    12. }
    13. // 3、如果D:\file不存在,则以目录的形式创建出来;mkdir()方法
    14. if (!f1.exists()) {
    15. f1.mkdir();
    16. }
    17. // 4、创建多重目录;mkdirs()方法
    18. File f2 = new File("D:/a/b/c/d");
    19. if (!f2.exists()) {
    20. f2.mkdirs();
    21. }
    22. // 5、获取当前文件的父路径
    23. File f3 = new File("D:\\python学习\\PyCharm Community Edition 2021.2.2");
    24. // 第一种:使用getParent(),返回的是一个String
    25. String parentPath = f3.getParent();
    26. System.out.println(parentPath); // D:\python学习
    27. // 第二种:使用getParentFile(),返回的是一个File;效果是一样的
    28. File parentFile = f3.getParentFile();
    29. System.out.println(parentFile); // D:\python学习
    30. // 6、获取当前文件的绝对路径
    31. File f4 = new File("file");
    32. System.out.println(f4.getAbsolutePath()); // C:\Users\86177\IdeaProjects\JavaSe1\file
    33. }
    34. }

    2.常用方法2

    (1)getName():获取当前文件的名字

    (2)isDirectory():判断是否是一个目录

    (3)isFile():判断是否是一个文件

    (4)lastModified():获取文件最后一次修改时间;得到的是毫秒数,返回long型

    (5)length():获取文件大小,结果是字节

    1. package com.bjpowernode.java.io;
    2. import java.io.File;
    3. import java.text.SimpleDateFormat;
    4. import java.util.Date;
    5. public class FileTest02 {
    6. public static void main(String[] args) {
    7. File f1 = new File("C:\\Java学习\\javaSE学习\\2.1JavaSE进阶笔记\\javase\\Copy02.java");
    8. // 1、获取文件名,getName()方法
    9. System.out.println("文件名:"+f1.getName()); // 文件名:Copy02.java
    10. // 2、判断是否是一个目录,isDirectory()方法
    11. System.out.println(f1.isDirectory()); // false
    12. // 3、判断是否是一个文件,isFile()方法
    13. System.out.println(f1.isFile()); // true
    14. // 4、获取文件最后一次修改时间,lastModified()方法
    15. // 得到的是毫秒数
    16. long modifytTime = f1.lastModified();
    17. // 将总毫秒数转换成日期
    18. Date date = new Date(modifytTime);
    19. // 格式化
    20. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
    21. System.out.println(sdf.format(date)); //2020-03-11 14:35:46 154
    22. // 5、获取文件大小,length()方法
    23. System.out.println(f1.length()); //1490 字节
    24. }
    25. }

    3.listFiles方法

    File中的listFiles方法获取当前目录下所有的子文件返回的是一个File[]数组

    1. package com.bjpowernode.java.io;
    2. import java.io.File;
    3. public class FileTest03 {
    4. public static void main(String[] args) {
    5. File f = new File("C:\\Java学习\\javaSE学习\\2.1JavaSE进阶笔记\\javase\\chapter15\\src");
    6. // 调用listFiles()方法,返回的是一个File[]数组
    7. File[] files = f.listFiles();
    8. // 用增强for循环打印
    9. for(File file :files){
    10. System.out.println(file.getAbsolutePath()); // 获取所有子目录的绝对路径
    11. System.out.println(file.getName()); //获取所有子目录的文件名
    12. }
    13. }
    14. }

    结束语

    今天的分享就到这里啦!快快通过下方链接注册加入刷题大军吧!各种大厂面试真题在等你哦!

     💬刷题神器,从基础到大厂面试题👉点击跳转刷题网站

  • 相关阅读:
    汇编 加法(二)
    云原生之容器编排实践-阿里云私有容器镜像仓库
    磁盘的结构
    损失函数&激活函数&学习率策略哇
    【JAVA类】利用接口的多继承实现———图书管理系统【附源码】
    使用 ggseg 对大脑分区统计结果进行可视化,如对皮层厚度差异T值进行可视化
    uniapp 中 vuex 的使用
    错误边界(Error boundary)
    NC17383 A Simple Problem with Integers
    金仓数据库 KingbaseGIS 使用手册(6.2. 管理函数)
  • 原文地址:https://blog.csdn.net/m0_61933976/article/details/126113071