IO流详解.

头歌 Java高级特性 - IO流 字节是指一小组相邻的二进制数码。通常是8位作为一个字节。它是构成信息的一个小单位,并作为一个整体来参加操作,比字小,是构成字的单位。字节(Byte) 是一种计量单位,表示数据量的多少,它是计算机信息技术用于计量存储容量的一种计量单位.我们想象一下,给你一串二进制码,要你来分辨它是什么含义,是代表数字还是字母还是汉字,你能有效的分辨吗?显然不能,一般来说,我们是比较难以理解一串二进制码代表的含义的,而且一串二进制码是代表什么含义也无法很直观的表示出来。我们比较好识别的是文字,字母和符号。所以就有了。 阅读详情

目录: 

一、IO流概述
二、FileInputStream初步
三、FileOutStream的使用
四、文件复制
五、FileReader的使用 
六、FileWriter的使用
七、复制普通文本文件
八、带有缓冲区的字符流
九、标准输出流(掌握)    / 写日志
十、File类

一、IO流概述

IO流: 什么是IO?
I:Input
O:Output        
(断电内存数据消失)

 1.1、IO流的分类

Io流的分类?
有多种分类方式:
    一种方式是按照流的方向进行分类:
    以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read)。从内存中出来,叫做输出(Output)。或者叫做写(Write)

    另一种方式是按照读取数据方式不同进行分类:
    有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制
    这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,
        假设文件file.txt,采用字节流的话是这样读的:
            a中国bc张三fe
            第一次读: 一个字节,正好读到'a'
            第二次读:一个字节,正好读到'中'字符的一半。
            第三次读: 一个字节,正好读到'中'字符的另外一半。


    有的流是按照字符的方式读取数据的,一次读取一一个字符,这种流是为了方便读取
    普通文本(.txt)文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯
    文本文件,连word文件都无法读取。
        假设文件file1. txt,采用字符流的话是这样读的:
            a中国bc第一fe
            第一次读: 'a'字符 ('a'字符在windows系统中占用1个字节。)
            第二次读: '中'中字符('中'字符在windows系统中占用2个字节。)

综上所述:流的分类
    输入流、输出流
    字节流、字符流

1.2、java Io流这块有四大家族

四大家族的首领: 
    java.io.Inputstream    字节输入流
    java.io.Outputstream    字节输出流
    java.io.Reader    字符输入流
    java.io.Writer    字符输出流
    
    四大家族的首领都是抽象类。(abstract class)
    注意:在java中只要"类名"以stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流
    
    所有的流都实现了:
        java.io.closeable接口,都是可关闭的,都有close()方法。
        流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
        不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
    
    所有的输出流都实现了:
        java.io.Flushable接口,都是可刷新的,都有flush()方法。
        养成一个好习惯,输出流在最终输出之后,一定要记得flush()
        刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据
        强行输出完(清空管道!)刷新的作用就是清空管道。
        注意:如果没有flush()可能会导致丢失数据。

 1.3、需要掌握哪些流(16个)

文件专属:(重点)
    java.io.FileInputstream(掌握)
    java.io.FileOutputstream(掌握)
    java.io.FileReader
    java.io.FileWri ter
转换流:(将字节流转换成字符流)
    java.io.InputstreamReader
    java.io .OutputstreamWri ter
缓冲流专属:
    java.io.BufferedReader
    java.io.BufferedWriter
    java.io.BufferedInputstream
    java.io.BufferedOutputstream
数据流专属:(了解)
    java.io.DataInputStream
    java.io.DataOutputstream
标准输出流:
    java.io.PrintWriter
    java.io.Printstream(掌握)
对象专属流:
    java.io.ObjectInputStream(掌握)
    java.io.Objectoutputstream(掌握)

二、FileInputStream初步

这个文件字节输入流直接看后面的结论代码即可,前面写的有点杂乱 大佬们多包涵~

代码演示如下:

这种一个一个读流的方式明显效率很低, 

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
FileInputStream :
    1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
    2、字节的方式,完成输入的操作,完成读的操作(硬盘----> 内存)

 */
public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fis =null;
        // 创建一个FileInputStream对象
        try {
             fis =new FileInputStream("D:\\IdeaProjects\\hello\\hello.txt");
             // 读流
            try {
                int file1 =fis.read();
                System.out.println(file1);
                int file2 =fis.read();
                System.out.println(file2);
                int file3 =fis.read();
                System.out.println(file3);
                int file4 =fis.read();
                System.out.println(file4);
                int file5 =fis.read();
                System.out.println(file5);
                int file6 =fis.read();
                System.out.println(file6);

            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 在finally语句块当中确保流一定关闭
            // 关闭流的前提是:流不是空,流是null的时候没必要关闭
            if (fis!=null){ // 避免空指针异常
            try {
                fis.close();
                System.out.println("流关闭成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        }
    }
}

输出结果: 

read()读取流的方法执行原理图:

将以上代码改进为循环读流:

代码演示如下: 

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

// 循环读流
public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fis =null;
        // 创建一个FileInputStream对象
        try {
            fis =new FileInputStream("D:\\IdeaProjects\\hello\\hello.txt");
            // 读流
            try {
                /* 循环读流 第一种
               while (true){
                   int fisData =fis.read(); // 读流
                   if (fisData==-1){
                       break;
                   }
                   System.out.println(fisData);
               }*/

                // 第二种循环方式:
                int readData =0;
                while ((readData =fis.read())!=-1){ // 将读出来的字节赋给readData 然后依次和-1比较
                    System.out.println(readData);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 在finally语句块当中确保流一定关闭
            // 关闭流的前提是:流不是空,流是null的时候没必要关闭
            if (fis!=null){ // 避免空指针异常
                try {
                    fis.close();
                    System.out.println("流关闭成功");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 输出结果:

 IDEA中的当前路径【重点】

 IDEA当前路径默认在工程Project的根

当寻找路径文件的时候会首先在工程根的目录下开始往下一步一步的寻找文件

 

这样写才是正确的 

七、

当返回的字节数量为0的时候(也就是文件里面没有元素的时候)返回-1 

 代码演示如下:

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest03 {
    public static void main(String[] args) {

        // 创建一个FileInputStream对象    文件字节输入流(硬盘----->内存)
        try {
            FileInputStream fis =new FileInputStream("chapter15\\src\\com\\bjpowernode\\java\\io\\tempFile.txt");
            // 可以先读进数组里面
            // 开始读,采用byte数组,一次读取多个字节,最多读取”数组.length“个字节
            byte[] bytes =new byte[4];  // 准备一个4个长度的byte数组,一次最多读取4个字节
            try {
                int readCount =fis.read(bytes);   // 这个方法返回值是:读取到的字节数量(不是字节本身) 读到4个
                System.out.println(readCount);    // 4个字节
                System.out.println(new String(bytes,0,readCount));   // 将字节数组全部转换成字符串

                int fisCount1 =fis.read(bytes);  // 读取到的字节数量 读取2个
                System.out.println(fisCount1);   // 2个字节
                System.out.println(new String(bytes,0,fisCount1));  // 把数组中的字节转换成字符串    不用下标限制的话 会输出efcd(看图)

                int fisCount2 =fis.read(bytes); // 读取的字节数量  读到0个
                System.out.println(fisCount2);  // 当文件里面的元素读完之后 输出结果为-1


            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

 改进循环:【终极版 会这个就行】【记住这个】

代码演示如下:

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest03 {
    public static void main(String[] args) {
        // 创建FileInputStream对象
        FileInputStream fis =null;
        try {
            fis =new FileInputStream("chapter15\\src\\com\\bjpowernode\\java\\io\\tempFile.txt");
            // 读流
            // 初始化一个数组
            byte[] bytes =new byte[4];
            while (true){
                try {
                    int fisCount =fis.read(bytes);  // 拿到的是字节数量
                    if (fisCount==-1){  // 字节数量为-1的时候说明文件里面没有元素了(读到了0个字节)
                        break;
                    }
                    // 能运行到这里说明文件还没有读取完
                    System.out.println(new String(bytes,0,fisCount));   // 把byte数组转换成字符串,读到多少个转换多少个

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (fis != null) {
                try {
                    fis.close();
                    System.out.println("流关闭成功");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

输出结果:

升级版:一定会这个

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest03 {
    public static void main(String[] args) {
        FileInputStream fis =null;
        try {
            fis =new FileInputStream("chapter15\\src\\com\\bjpowernode\\java\\io\\tempFile.txt");
            // 初始化一个数组
            byte[] bytes =new byte[4];    
            // 读流
            /*while (true){
                int readCount =fis.read(bytes); // 往数组里面读 读取的是字节数量
                if (readCount==-1){
                    break;
                }
                System.out.println(new String(bytes,0,readCount));
            }*/
            
            // 升级版
            int readCount =0;
            while ((readCount =fis.read(bytes))!=-1){   // 把每次循环读的字节数量赋给readCount 然后与-1判断 等于-1的话该分支结束
                // 循环里面的fis.read(bytes))!=-1,只要不为-1,就一直在往bytes数组里面读取着数据呢,这时数组中已经一直有读取到的数据了。

                System.out.println(new String(bytes,0,readCount)); // 可以验证出确实bytes数组中确实读取到了数据
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {    // 在finally语句块当中确保流一定关闭(因为如果前面的代码出现异常了,但是finally块还是能执行了,所以在finally块中关闭流确保了流的关闭)
            // 关闭流的前提是:流不是空,流是null的时候没必要关闭

            if (fis != null) {    // 避免空指针异常
                try {
                    fis.close();
                    System.out.println("流关闭成功");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

当文件内容不太大的时候,可以用下列方法一次读取完内容 【一定要会】

FileInputStream类的其他常用方法:
        int available()  : 返回流当中剩余的没有读到的字节数量
        long skip(long n) : 跳过几个字节不读 

代码演示如下: 

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest04 {
    public static void main(String[] args) {
        // 创建FileInputStream对象
        FileInputStream fis =null;
        try {
            fis =new FileInputStream("chapter15/src/com/bjpowernode/java/io/UserFile");
            // 还没有读的时候文件中的总字节数量:
            // System.out.println("文件中的总字节数量:"+fis.available());   // 5
            // 读一个字节
            // int readData =fis.read();
            // 文件中还剩下可以读的字节数量是:     (文件中数据:abcde)
            // System.out.println("剩下多少字节没有读:"+fis.available());   // 4

            
            // int available() 这个方法可以怎么用呢?
            // : 当文件中的数据不太大的时候可以直接把总字节数量放入一个数组里面一次读取完(注意:当文件过大时不能直接放到数组当中:扩容问题影响效率)
            byte[] bytes =new byte[fis.available()];    // 直接把文件中的总字节数量放到数组里面
            // 不需要循环了
            // 直接一次读就行了
            int readData1 =fis.read(bytes);    // 读到数组里面 读到的是字节数量
            System.out.println(readData1);  // 5
            System.out.println(new String(bytes));  //abcde  直接把数组转换成字符串


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                // 关闭流
                try {
                    fis.close();
                    System.out.println("流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

三、FileOutStream的使用

文件字节输出流
从内存 ---->硬盘

代码演示如下: 

package com.bjpowernode.java.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutStreamTest01 {
    public static void main(String[] args) {
        FileOutputStream fos =null;

        // 注意:这种方式谨慎使用,这种方式会先将原文件清空,然后重写写入
        
        try {
            fos =new FileOutputStream("OutputStreamFile");    // 新文件
            // 开始写
            byte[] bytes ={97,98,99,100,101};
            // 将byte数组全部写到硬盘
            fos.write(bytes);   // 将数组里面的内容写入到”OutputStreamFile”文件里面(当文件不存在的时候自动新建到项目根目录)
            // 将byte数组的一部分写到硬盘
            fos.write(bytes,0,2);   // 从0开始2个长度 ab
            
            // 写完之后一定要刷新
            fos.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    System.out.println("流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

输出结果:

注意:这里会先清空原文件当中的内容,然后把abcde和ab重写写入到该文件当中

 对以上缺点进行改进代码演示如下:

// 以追加的方式在文件末尾写入,不会清空原文件内容
package com.bjpowernode.java.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

// 以追加的方式在文件末尾写入,不会清空原文件内容
public class FileOutStreamTest02 {
    public static void main(String[] args) {
        FileOutputStream fos =null;
        try {
            fos =new FileOutputStream("chapter15/src/com/bjpowernode/java/io/tempFile.txt",true);   // 追加的构造方法
            // 开始写
            byte[] bytes ={97,98,99,100,101};
            fos.write(bytes);

            // 也可以写字符串形式,然后把字符串转换成数组格式
            String s ="我是中国人,我爱中国,中国加油,中国之国~";
            byte[] bytes1 =s.getBytes();    // 将字符串转换成数组
            fos.write(bytes1);  // 把该数组当中的内容写入到文件当中

            // 刷新管道
            fos.flush();
            System.out.println("流刷新成功~");
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    System.out.println("流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 输出结果:

 四、文件复制

使用FileInputStream + FileOutputStream完成文件的拷贝
拷贝的过程应该是一边读,一边写
使用以上的字节流拷贝文件的时候,文件类型随意,万能的,什么样的文件都能拷贝

思想如图所示: 

代码演示如下: 

注意:如果拒绝访问就以管理员的身份进入IDEA

package com.bjpowernode.java.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyTest01 {
    public static void main(String[] args) {
        FileInputStream fis =null;
        FileOutputStream fos =null;
        try {
            // 把D盘中的文件复制到C盘

            // 创建一个输入流对象
            fis =new FileInputStream("D:\\画图总部\\面向对象思想图.png");
            // 创建一个输出流对象
            fos =new FileOutputStream("C:\\面向对象思想图.png");

            // 核心 : 一边读一边写
            byte[] bytes =new byte[1024 *1024]; // 以1MB拷贝
            int readCount =0;   // 数组的字节数量
            while ((readCount = fis.read(bytes))!=-1){   // 从文件中读进数组里面 只要不为-1就一直读,为-1说明读取完了
                // 写
                fos.write(bytes,0,readCount);   // 边读边写入
            }

            // 刷新,输出流最后要刷新
            fos.flush();
            System.out.println("输出流刷新成功~");
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 注意:分开try,不要一起try
            // 一起try的时候,其中一个出现异常,可能会影响到另外一个流的关闭
            if (fis != null) {
                try {
                    fis.close();
                    System.out.println("输入流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                    System.out.println("输出流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

五、FileReader的使用 

FileReader:
    文件字符输入流,只能读取普通文本
    读取文字内容时,比较方便,快捷

代码演示如下:(比葫芦画瓢~)

package com.bjpowernode.java.io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderTest01 {
    public static void main(String[] args) {
        // 创建一个FileReader对象
        FileReader fr =null;
        try {
            // 创建文件字符输入流
            fr =new FileReader("chapter15/src/com/bjpowernode/java/io/UserFile");
            // 开始读
            char[] chars =new char[4];
            int readCount =0;
            while ((readCount =fr.read(chars))!=-1){
                System.out.println(new String(chars,0,readCount));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                    System.out.println("流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

输出结果:

六、FileWriter的使用

代码演示如下:(比葫芦画瓢)

package com.bjpowernode.java.io;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterTest01 {
    public static void main(String[] args) {
        FileWriter fw =null;
        try {
            fw =new FileWriter("chapter15/src/com/bjpowernode/java/io/UserFile");
            // 开始写
            char[] chars ={'我','是','中','国','人'};
            fw.write(chars);    // 全部写入
            fw.write(chars,2,3);    // 中国人 2是开始位置3是长度
            // 注意这里: 再一次运行该程序的时候 首先会把原文件中的内容清空 然后把我是中国人中国人写入该文件当中

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fw != null) {
                try {
                    fw.close();
                    System.out.println("流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 七、复制普通文本文件

使用FileReader、FileWriter进行拷贝演示,只能拷贝“普通文件”(能用记事本打开编写的都是普通文件)

代码演示如下:

package com.bjpowernode.java.io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyTest02 {
    public static void main(String[] args) {
        FileReader fr =null;
        FileWriter fw =null;
        try {
            // 创建字符输入流对象
            fr =new FileReader("chapter15/src/com/bjpowernode/java/io/UserFile");
            // 创建字符输出流对象
            fw =new FileWriter("UserFile"); // 默认路径为根目录下

            // 核心:一边读、一边写
            char[] chars =new char[1024 *1024]; // 1MB
            int readCount =0;
            while ((readCount =fr.read(chars))!=-1){    // 读1MB的数据放到char[]数组当中
                // 边读边写入文件
                fw.write(chars,0,readCount); // 把每次写入到数组当中的数据写入文件当中
            }

            // 管道刷新
            fw.flush();
            System.out.println("管道刷新成功~");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 分开try
            // 一起try的话如果第一个发生了异常 第二个字符输出流就关闭不了
            if (fr != null) {
                try {
                    fr.close();
                    System.out.println("字符输入流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                    System.out.println("字符输出流关闭成功~");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

八、带有缓冲区的字符流

1、 

BufferedReader : 缓冲输入字符流 

代码演示如下: 

package com.bjpowernode.java.io;
import java.io.*;
/*
BufferedReader:
    带有缓冲区的字符输入流
    使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组,自带缓冲

public BufferedReader(Reader in) : 构造方法中Reader是一个抽象类,FileReader继承了该抽象类

BufferedReader类当中的常用方法:
    String readLine()
        读一行文字。
    // 当没有读取到任何文字的时候返回null

 */

public class BufferReaderTest01 {
    public static void main(String[] args) throws IOException {
        // 创建子类FileReader对象
        FileReader Reader =new FileReader("UserFile");
        BufferedReader br =new BufferedReader(Reader);    // 多态 父类型引用指向子类型对象 (FileReader继承了Reader该抽象类) 相当于把文件夹传了过来
        // 记住: FileReader: 节点流    BufferedReader: 包装流/处理流

        // 读取文件夹

        /*
           读一行
        String firstLine =br.readLine();
        System.out.println(firstLine);

        String secondLine =br.readLine();
        System.out.println(secondLine);
         */

        // 注意:br.readLine()方法读取一个文本行,但不带换行符(换行是因为我们输出的时候是println,ln换行)
        String s =null;
        while ((s =br.readLine())!=null){   // 当读取文件内容不是null的时候 说明有数据
            System.out.println(s);  // 输出文件内容
        }

        // 关闭流
        // 对于包装流来说,只需要关闭最外层流就可以,里面的节点流会自动关闭 (别问,问就是看过源码~)
        br.close();
    }
}

输出结果:

1.2、

 当输入字节流:FileInputStream对象的时候 怎么利用缓冲的方法读取文件 

代码演示如下:

package com.bjpowernode.java.io;
import java.io.*;

public class BufferReaderTest02 {
    public static void main(String[] args) throws IOException {
        // 字节流
        // FileInputStream fis =new FileInputStream("UserFile");

        // 通过转换流转换(InputStreamReader将字节流转换成字符流)
        // fis是节点流 reader 是包装流
        // InputStreamReader reader =new InputStreamReader(fis);

        // 这里的BufferedReader类当中的构造方法只能传一个字符流,不能传字节流
        /*
        构造方法当中Reader是一个抽象类 InputStreamReader继承了该抽象类
        所以可以把字节流先转换成字符流 然后该字符流继承了Reader抽象类 利用多态 能够传进去
         */
        // BufferedReader br =new BufferedReader(reader);
        // reader是节点流 br是包装流

        // 合并上述代码
        BufferedReader br =new BufferedReader(new InputStreamReader(new FileInputStream("UserFile")));

        // 读
        String s =null;
        while ((s=br.readLine())!=null){
            System.out.println(s);
        }

        // 关闭最外层
        br.close();
    }
}

 输出结果:

BufferedWriter: 带有缓冲的字符输出流
OutputStreamWriter:转换流

 代码演示如下:

package com.bjpowernode.java.io;
import java.io.*;

/*
BufferedWriter: 带有缓冲的字符输出流
OutputStreamWriter:转换流
 */
public class BufferedWriterTest01 {
    public static void main(String[] args) throws IOException {
        // 带有缓冲区的字符输出流
        // BufferedWriter out =new BufferedWriter(new FileWriter("copy"));
        BufferedWriter out =new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copy")));   // 能个true追加

        // 开始写
        out.write("hello world");
        out.write("\n");    // 换行符
        out.write("kitty");

        // 刷新
        out.flush();
    }
}

输出结果:

九、标准输出流(掌握)

代码演示如下:

package com.bjpowernode.java.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamTest01 {
    public static void main(String[] args) throws FileNotFoundException {
        // 联合起来写
        System.out.println("hello world");  // 将"hello world" 输出到控制台

        PrintStream ps =System.out; // System.out 返回的是一个PrintStream
        // 分开写
        ps.println("junker");
        ps.println("kitty");

        // 标准输出流不需要手动close()关闭

        // 我们可以改变标准输出流的输出方向吗? 可以

        // 标准输出流不再指向控制台,指向了“psFile”文件
        PrintStream printStream =new PrintStream(new FileOutputStream("psFile"));
        // 修改输出方向,将输出方向修改到“psFile”文件
        System.setOut(printStream);
        // 再输出
        System.out.println("hello world");
        System.out.println("hello kitty");

    }
}

 可以利用该标准输出流写日志【重点】

代码演示如下:

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 Longer {
    // 创建一个记录日志的方法
    public static void log(String msg){ // msg代表日志信息    // 此处可以写成Object类型
        try {
            // 指向一个日志文件
            PrintStream printStream =new PrintStream(new FileOutputStream("msgFile",true)); // 追加[不会清空内容]
            // 改变输出方向
            System.setOut(printStream);

            // 日期当前时间
            Date date =new Date();
            // 格式化时间
            SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss SSS");
            String strTime =simpleDateFormat.format(date);

            // 输出
            System.out.println(strTime +":" +msg);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

代码测试:

package com.bjpowernode.java.io;

public class RiZhiTest {
    public static void main(String[] args) {
        // 测试日志
        Longer.log("调用了Longer的方法");
        Longer.log("登录了系统注册功能");
        Longer.log("修改了密码");
        Longer.log("注册账户失败了");
    }
}

 十、File类

File
1、File类和四大家族没有关系,所以File类不能完成文件的读和写。
2、File对象代表什么?
    文件和目录路径名的抽象表示形式
    C:\Drivers这是一个File对象
    C: \Drivers\Lan\Realtek\Readme.txt也是File对象。
一个File对象有可能对应的是目录(文件夹),也可能是文件。
File只是一个路径名的抽象表示形式。
3、需要掌握File类中常用的方法

File类常用方法代码演示如下: 

package com.bjpowernode.java.io;
import java.io.File;
import java.io.IOException;


public class FileTest01 {
    public static void main(String[] args) throws IOException {
        File file =new File("D:\\file");
        //  第一种  boolean exists();
        // 判断指定的位置文件是否存在
        System.out.println(file.exists());  // false

        // 第二种:如果C:/file不存在,则以文件的形式创建出来(不是文件夹)
        // if(!file.exists()){
        //     file.createNewFile();
        // }
        // 第三种:如果C:/file不存在,则以目录(文件夹)的形式创建出来
        if (!file.exists()){
            file.mkdir();
        }

        //  第四种:可以创建多重目录(文件夹)吗 ? 比如a\b\c\d\e
        File file1 =new File("D:\\a\\b\\c\\d\\e");
        // 如果该文件不存在,那么就多重创建
        if (!file1.exists()){
            // 多重目录的形式新建
            file1.mkdirs();
        }

        //  第五种:获取文件的父路径(两种获取方式)
        File file2 =new File("D:\\java course\\day01\\HelloWorld.java");
        String s =file2.getParent();
        System.out.println(s);  // D:\java course\day01

        File f =file2.getParentFile();
        System.out.println(f);  // D:\java course\day01

        // 第六种:获取绝对路径
        File f1 =file2.getAbsoluteFile();
        System.out.println(f1); // D:\java course\day01\HelloWorld.java
    }
}
package com.bjpowernode.java.io;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
File类常用方法
 */

public class FileTest02 {
    public static void main(String[] args) {
        File file =new File("D:\\java course\\renSheng\\House.java");

        // 获取文件名
        System.out.println(file.getName()); // House.java

        // 判断是否是一个目录(文件夹)
        System.out.println(file.isDirectory()); // false

        // 判断是否是一个文件
        System.out.println(file.isFile());  // true

        // 获取文件最后一次修改的时间
        long HaoMiao =file.lastModified();  // 这个毫秒是从1970年到现在的总毫秒数
        // 如何将毫秒转化成日期?
        Date date =new Date(HaoMiao);
        // 初始化日期
        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String s =simpleDateFormat.format(date);
        System.out.println(s);  // 2022-02-22 17:17:43 783

        // 获取文件大小
        System.out.println(file.length());  // 93   93个字节

    }
}

File中的listFile方法: 获取当前目录下的所有子文件 

代码演示如下: 

package com.bjpowernode.java.io;
import java.io.File;

// File中的listFiles方法
public class FileTest03 {
    public static void main(String[] args) {
        // File[] listFiles()方法
        // 获取当前目录(文件夹)下所有的子文件
        File file =new File("D:\\java course\\renSheng");
        File[] files=file.listFiles();

        // 对数组循环遍历
        for (File data : files){
            // 拿到绝对路径
            System.out.println(data.getAbsolutePath());
            // System.out.println(data.getName());  // 拿到名字
        }
    }
}

输出结果:

 

面试官:请讲一讲IO流核心模块与基本原理是什么? 前言 一、IO流与系统 IO技术在JDK中算是极其复杂的模块,其复杂的一个关键原因就是IO操作和系统内核的关联性,另外网络编程,文件管理都依赖IO技术,而且都是编程的难点,想要整体理解IO流,先从Linux操作系统开始。 Linux空间隔离 Linux使用是区分用户的,这个是基础常识,其底层也区分用户和内核两个模块: User space:用户空间 Kernel space:内核空间 常识用户空间的权限相对内核空间操作权限弱很多,这就涉及到用户与内核两个模块间的交互,此时部署在服务上的应用如果需要请求系 阅读详情

相关推荐

Java高级特性 - IO流

任务描述本关任务:完成选择题。相关知识为了完成本关任务,你需要掌握:1.什么是字节、字符;2.什么是输入流、什么是输出流。什么是字节字节是指一小组相邻的二进制数码。通常是8位作为一个字节。它是构成信息的一个小单位,并作为一个整体来参加操作,比字小,是构成字的单位。字节(Byte) 是一种计量单位,表示数据量的多少,它是计算机信息技术用于计量存储容量的一种计量单位.第 1 题BC第 2 题C。

Junds0的博客 1872

IO流 (字节流、字符流)

IO流的作用:就是可以对文件或者网络中的数据进行读、写的操作。如下图所示IO流在Java中有很多种,不同的流来干不同的事情。Java把各种流用不同的类来表示,这些流的继承体系如下图所示:IO流分为两大派系:1.字节流:字节流又分为字节输入流、字节输出流2.字符流:字符流由分为字符输入流、字符输出流。

qq_46030254的博客 7159

双有源桥变换器(DAB)TPS控制:从理论建模到Simulink/PSIM仿真实践

本文深入探讨了双有源桥变换器(DAB)的三重移相(TPS)控制技术,从理论建模到仿真实现。文章详细分析了TPS相比SPS和DPS的优势,阐述了其12种工况的划分逻辑与电流应力最优调制策略,并提供了在Simulink和PSIM平台搭建仿真模型的详细步骤与实战经验,帮助工程师掌握这一高效控制方法。

white的博客 584

最全最详细的IO流教程

最全最详细的IO流教程

奔跑的熊猫 9345

立创开源PEX88048 8盘位M.2扩展卡硬件设计与PCIE4.0交换机应用解析

本文详细解析了基于Broadcom PEX88048 PCIe 4.0交换芯片的8盘位M.2扩展卡硬件设计。文章深入探讨了核心芯片选型、关键供电与安全设计、引脚配置、固件刷写方法,并重点剖析了PCIe 4.0时钟架构与高速PCB布局的核心思想,旨在帮助开发者理解如何设计高性能、高可靠性的存储扩展方案,并有效控制成本。

weixin_28949937的博客 619

保姆级教程:用Cesium的Primitive API实现火箭发射全流程动画(含代码避坑)

本文详细介绍了如何使用Cesium的Primitive API实现火箭发射全流程动画,包括模型控制、关节动画和精细时序管理。通过实战代码示例和性能优化技巧,帮助开发者高效构建高复杂度航天仿真系统,显著提升三维可视化效果与运行效率。

weixin_42565652的博客 213

详解IO流

Java IO详解IO概述1.什么是IO2.流及流的分类2.1什么是流?2.2流的分类3.IO流对象3.1字节流4.IO流方法4.1字符流方法4.2字节流方法5.代码实例5.1使用`FileReader`和`FileWriter`实现文本的复制5.2使用`FileInputStream`和`FileOutputStream`实现图片的复制 IO概述 1.什么是IO I/O是Input/Out普通的缩写,I/O技术是非常使用的技术,用于处理设备之间的数据传输。 在Java程序中,对于数据的输入/输出操作以“流

蛙广志 627

模型可解释性分析:基于SHAP的深度探索

SHAP模型可解释性分析摘要 本文系统性地介绍了SHAP(SHapley Additive exPlanations)方法在机器学习模型可解释性分析中的应用。SHAP基于博弈论的Shapley值理论,为特征重要性评估提供了统一框架。文章详细阐述了四种核心算法:Kernel SHAP(模型无关方法)、Tree SHAP(针对树模型的高效算法)、Deep SHAP(适用于深度学习)和Linear SHAP(线性模型专用)。通过Python实现展示了从数据准备到SHAP分析的全流程,包括摘要图、依赖图等可视化技术

huanghm88的专栏 611

【Java IO流】IO流详解

IO,即InputOutput,也就是输入和输出,指应用程序和外部设备之间的数据传递,常见的外部设备包括磁盘文件、管道、网络连接Java中是通过流处理IO的,那么什么是流?流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道当Java程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是磁盘文件、内存、网络连接等等。类似地,当Java程序需要写入数据的时候,就会开启一个通向目的地的流。

m0_55908255的博客 1695

VTK 显示大量点云数据及交互(点云拾取、着色、测量等)功能

VTK (Visualization Toolkit) 是一个强大的开源可视化库,非常适合处理点云数据。下面将介绍如何使用 VTK 显示大量点云数据,并实现点云拾取、着色、测量等功能。

深之JohnChen的专栏 1996

基于高德地图的单车路径规划与绘制实战(Vue3 + TypeScript)【拓展:货车路径规划函数、限行检测、城市 Adcode】

✅ 支持单辆车路径规划✅ 自动绘制路线✅ 起点、终点、途经点标注✅ 自动缩放视野至全路径✅ 获取路线距离、时长、过路费✅ 提供清除功能✅ 路线信息保存至本文完整实现了一个基于高德地图 JS SDK + Vue3 + TypeScript的👉单车路径规划与绘制模块。核心亮点:清晰的结构;灵活的扩展性;实时路线信息记录(🚀 你可以很方便地将本模块集成到车联网、调度监控、地图展示类项目中。❤️ 如果这篇文章对你有帮助,别忘了:评论区交流 💬。

专注于前端开发与实战技巧,记录从零到一的学习与项目经验。分享 Vue3 / JavaScript / TypeScript / Flutter /Uniapp等前端技术,以及 性能优化、工程化、最佳实践。 1264

【C++】IO流详解

在C语言中,如果想要将一个整形变量的数据转化为字符串格式,如何去做?使用itoa()函数使用sprintf()函数但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用类对象来避开此问题。在程序中如果想要使用,必须要包含头文件。和,分别用来进行流的输入、输出和输入输出操作,本文主要介绍 stringstream。

lirendada的博客 4437

深度学习-161-Dify工具之对比使用工作流和聊天流生成图表可视化的html文件

分别使用聊天流和工作流进行数据分析结果的可视化,生成html文件。聊天流可以配置带记忆,这样就可以多次交互优化结果。

qq_20466211的博客 1709

Java IO流详解

原文 Java IO流详解 1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。 IO又分为流IO(java.io)和块IO(java.nio) Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的

ss810540895的博客 1万+

【YOLO11改进 - C3k2融合】C3k2融合动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务

【YOLO11改进 - C3k2融合】C3k2融合动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 518

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java:IO流详解

Java:IO流详解

游手好闲 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

IO流的详解,彻底了解IO流

Java对数据的操作是通过流的方式,学好IO流可以方便地实现数据的输入/输出操作,其重要性不言而喻。以下是本篇文章的思维导图以上就是今天要讲的内容,本文从操作系统进行文件读写入手,对同步、异步、阻塞、非阻塞以及它们组合而成的IO模式进行了介绍,还介绍了Linux操作系统中的五种IO模型,相信大家应该有了一定的了解。如有不恰当的地方,还请雅正。参考资料:1.要问技术多NB,请问IO模型知多少?2.Java IO流详解3.Java中五中IO模型详解文章知识点与官方知识档案匹配,可进一步学习相关知识。

菠萝吹雪爱Java的博客 2949

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IO流详解

文章目录IO流的概念基本分类体系结构相关流详解FileWriterFileReaderFileOutputStreamFileInputStreamBufferedOutputStreamBufferedInputStreamBufferedWriterBufferedReaderPrintStreamPrintWriterOutputStreamWriterInputStreamReaderDataOutputStreamDataInputStreamObjectOutputStreamObjectInp

亦翼的博客 1471

IO流【详解】

Input 输入Output 输出流: 例如水流,流量,即流是指数据流动传输IO流就是指数据的输入输出例如: 将磁盘中的小说.txt,读取到java代码中 ---> 输入例如: 从java代码中,写到磁盘中创建出文件,并向文件中写入内容 --> 输出。

weixin_61898502的博客 947

【Java】各种IO流知识详解

Java IO流是Java编程中用于处理输入输出操作的核心机制,它提供了一套统一的接口来处理不同类型的数据源和目标。无论是文件操作、网络通信还是内存数据处理,IO流都扮演着关键角色。IO流(Input/Output Stream)是Java中用于数据传输的抽象概念。流代表了一个有序的数据序列,数据可以从一个地方流向另一个地方。IO流的设计模式采用了装饰器模式,通过组合不同的流来实现复杂的功能。Java IO流主要分为两大类:字节流和字符流,每种又分为输入流和输出流。 具体分类 字节流:处理二进制数据,如图

WizLC 970

java IO流详解

🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓JavaIO流详解,做好准备了么,那么开始吧 🌲🌲🐴🐴

weixin_62275996的博客 1235
上一篇: 递归详解.
下一篇: 拷贝目录详解.
lwj_07
博客等级 码龄5年 678粉丝 153原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值