> 文档中心 > 深入理解Java IO流(第二篇)

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


 ✅作者简介:大家好我是@每天都要敲代码,一位材料转码农的选手,希望一起努力,一起进步!
📃个人主页:@每天都要敲代码的个人主页
💬推荐一款模拟面试、刷题神器,从基础到大厂面试题👉点击跳转刷题网站进行注册学习

目录

🥅缓冲流

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

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

2.字符输出流BufferedWriter

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

🥅转换流

1.OutputStreamWriter

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

OutputStreamWriter:转换流

package com.bjpowernode.java.io;import java.io.*;public class BufferedWriterTest01 {    public static void main(String[] args) throws IOException { // 创建带有缓冲区的字符输出流 BufferedWriter writer = new BufferedWriter(new FileWriter("file")); // 如果想要使用字节输出流,还是需要OutputStreamWriter进行流的转换 // 如果使用的是字节流 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file")); BufferedWriter writer1 = new BufferedWriter(osw);  // 合并在一起 BufferedWriter writer1 = new BufferedWriter(new OutputStreamWriter (new FileOutputStream("file"))); // 开始写 writer.write("hello world!"); writer.write("\n"); writer.write("hello kitty!"); // 刷新 writer.flush(); // 关闭最外层 writer.close();    }}

2.InputStreamReader

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

需要使用转换流:InputStreamReader,把将字节流转换成字符流

package com.bjpowernode.java.io;import java.io.*;public class BufferedReaderTest02 {    public static void main(String[] args) { FileInputStream fis = null; try {     // 字节流     fis = new FileInputStream("file");     // 通过转换流转换(InputStreamReader将字节流转换成字符流)     // fis是节点流。reader是包装流。     InputStreamReader reader = new InputStreamReader(fis);     // 把转换成字符流的字节流,传过来     // reader是节点流。br是包装流。     BufferedReader br = new BufferedReader(reader);     // 上面进行合并     BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("file")));     // 进行打印     String s = null;     while((s = br1.readLine()) != null){  System.out.println(s);     }     // 关闭     br.close(); // 关闭最外层 } catch (FileNotFoundException e) {     e.printStackTrace(); } catch (IOException e) {     e.printStackTrace(); } finally {     if (fis != null) {  try {      fis.close();  } catch (IOException e) {      e.printStackTrace();  }     } }    }}

🥅数据流

1.DataOutputStream

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

package com.bjpowernode.java.io;import java.io.DataOutputStream;import java.io.FileOutputStream;public class DataOutputStreamTest01 {    public static void main(String[] args) throws Exception{ // 创建数据专属的字节输出流(写) DataOutputStream dos = new DataOutputStream(new FileOutputStream("file")); //生成的这个文件,记事本打不开 // 写数据 byte b = 100; short s = 200; int i = 300; long l = 400L; float f = 3.0F; double d = 3.14; boolean sex = false; char c = 'a'; // 写;把数据以及数据的类型一并写入到文件当中dos.writeByte(b);dos.writeShort(s);dos.writeInt(i);dos.writeLong(l);dos.writeFloat(f);dos.writeDouble(d);dos.writeBoolean(sex);dos.writeChar(c); // 刷新 dos.flush();  // 关闭最外层 dos.close();    }}

2.DataInputStream

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

package com.bjpowernode.java.io;import java.io.DataInputStream;import java.io.FileInputStream;public class DataInputStreamTest01 {    public static void main(String[] args) throws Exception { // 创建数据专属的字节输入流(读) DataInputStream dis = new DataInputStream(new FileInputStream("file")); // 开始读 byte b = dis.readByte(); short s = dis.readShort(); int i = dis.readInt(); long l = dis.readLong(); float f = dis.readFloat(); double d = dis.readDouble(); boolean sex = dis.readBoolean(); char c = dis.readChar(); // 打印 System.out.println(b); System.out.println(s); System.out.println(i); System.out.println(l); System.out.println(f); System.out.println(d); System.out.println(sex); System.out.println(c); // 关闭流 dis.close();    }}

🥅标准输出流

1.PrintStream

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

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

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

2.日志工具类

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

日志框架

package com.bjpowernode.java.io;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.text.SimpleDateFormat;import java.util.Date;// 日志工具public class Logger {    // 记录日志的方法   public static void log(String msg) {try {    PrintStream out = new PrintStream(new FileOutputStream("log.txt",true));    // 改变流的方向    System.setOut(out);    // 获取系统当前时间    Date nowDate = new Date();    // 格式类型转换    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");    String myNowdate = sdf.format(nowDate);    // 打印    System.out.println(myNowdate+":"+msg);} catch (FileNotFoundException e) {    e.printStackTrace();}   }}

日志测试

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

🥅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()方法:获取当前文件的绝对路径

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

2.常用方法2

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

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

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

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

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

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

3.listFiles方法

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

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

 

结束语

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

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