IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> File类与IO流 -> 正文阅读

[Java知识库]File类与IO流

File类

java.io.File类
文件和目录路径名的抽象表示形式
Java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作
我们可以使用File类的方法
创建一个文件/文件夹
删除文件/文件夹
获取文件/文件夹
判断文件/文件夹是否存在
对文件夹进行遍历
获取文件的大小
File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法
重点:file:文件 directory:文件夹/目录 path:路径

File类的静态成员变量

static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串
static char pathSeparatorChar 与系统有关的路径分割符
static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串
static char separatorChar 与系统有关的默认名称分隔符
注意:操作路径,不能写死了,应该以=="+File.separator+"==代替正反斜杠
windows:C:\develop\a\a.txt
linux:C:/develop/a/a.txt
“C:”+File.separator+“develop”+File.separator+“a”+File.separator+“a.txt”

public class Demo01File {
    public static void main(String[] args) {
        //static String pathSeparator  与系统有关的路径分隔符,为了方便,它被表示为一个字符串
        String pathSeparator = File.pathSeparator;
        System.out.println(pathSeparator);//;路径分隔符,windows分号Linux为冒号
        //static String separator  与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串
        String separator = File.separator;
        System.out.println(separator);//\文件名称分隔符,windows反斜杠linux为正斜杠
    }

绝对路径和相对路径

路径:
绝对路径:完整的路径
以盘符(C、D)开始的路径 E:\soft\IDEA
相对路径:简化的路径
相对指的是相对于当前项目的根目录
如果使用当前项目的根目录,可以简化书写
E:\soft\IDEA–>IDEA(可以省略项目的根目录)
注意:1、路径是不区分大小写的
2、路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

File类的构造方法

File(String pathname)通过将给定路径名字字符串转换为抽象路径名来创建一个新File实例
File(String parent,String child)根据parent路径名字符串和child路径名字符创建一个新的File实例
File(File parent,String child)根据parent抽象路径和child路径名字符串创建也给新的File实例

public class Demo02File {
    public static void main(String[] args) {
        //File类的构造方法
        show01();
        show02("c:\\","a.txt");
        show03();

    }

    //File(String pathname)通过将给定路径名字字符串转换为抽象路径名来创建一个新File实例
    //参数:String pathname:字符串的路径
    //路径可以是以文件结尾,也可以是以文件夹结尾
    //路径可以是相对路径,也可以是绝对路径
    //路径可以是存在的,也可以是不存在的
    //创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况

    private static void show01() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");//绝对的文件
        System.out.println(f1);//D:\java\ceshi\day01\a.txt 重写了toSting方法

        File f2 = new File("D:\\java\\ceshi\\day01\\xiaohaha");//绝对的文件夹
        System.out.println(f2);

        File f3 = new File("b.txt");//相对路径
        System.out.println(f3);
    }

    //File(String parent,String child)根据parent路径名字符串和child路径名字符创建一个新的File实例
    //参数:把路径分为了两部分
    //  String parent:父路径
    //  Strign child:子路径
    //好处:父路径和子路径,可以单独书写,使用起来非常灵活,父路径和子路径都可以变化

    private static void show02(String parent,String child) {
        File file = new File(parent,child);
        System.out.println(file);//c:\a.txt
    }

    //File(File parent,String child)根据parent抽象路径和child路径名字符串创建也给新的File实例
    //参数:把路径分成了两部分
    //  String parent:父路径
    //  String child:子路径
    //好处:路径可以随时变化,父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建都行
    private static void show03() {
        File parent = new File("c:\\");
        File file = new File(parent,"hello.java");//可以使用File的方法对路径进行一些操作
        System.out.println(file);//c:\hello.java
    }
}

File类获取功能的方法

public String getAbsolutePath():返回File的绝对路径名字符串
public String getPath():将此file转换为路径名字符串
public String getName():返回由此file表示的文件或目录的名称
public long length():返回由此file表示的文件长度

public class Demo03File {
    public static void main(String[] args) {
        show01();
        show02();
        show03();
        show04();
    }

    //public String getAbsolutePath():返回File的绝对路径名字符串
    //获取的是构造方法中传递的路径
    //无论路径是绝对的还是相对的,getAbsolutePath()方法返回的都是绝对路径
    private static void show01() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        String absolutePath1 = f1.getAbsolutePath();
        System.out.println(absolutePath1);//D:\java\ceshi\day01\a.txt

        File f2 = new File("a.txt");
        String absolutePath2 = f2.getAbsolutePath();
        System.out.println(absolutePath2);//D:\java\zgDaren\a.txt

    }
    //public String getPath():将此file转换为路径名字符串
    //获取的是构造方法中传递的路径
    //toSting调用的也就是getPath方法
    //源码:public String toString(){
    //       return getPath();
    //     }

    private static void show02() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        File f2 = new File("a.txt");
        String path1 = f1.getPath();
        System.out.println(path1);//D:\java\ceshi\day01\a.txt
        String path2 = f2.getPath();
        System.out.println(path2);//a.txt

        System.out.println(f1);//D:\java\ceshi\day01\a.txt 重写了toString方法
        System.out.println(f1.toString());//D:\java\ceshi\day01\a.txt

    }

    //public String getName():返回由此file表示的文件或目录的名称
    //获取的就是构造方法传递路径的结尾部分(文件/文件夹)

    private static void show03() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        String name1 = f1.getName();
        System.out.println(name1);//a.txt
        File f2 = new File("D:\\java\\ceshi\\day01");
        String name2 = f2.getName();
        System.out.println(name2);//day01
    }

    //public long length():返回由此file表示的文件长度
    //获取的是构造方法指定的文件大小,以字节为单位
    //注意:问价夹是没有大小概念的,不能获取文价夹的大小
    //     如果构造方法中给出的路径不存在,那么length方法返回的值为0
    private static void show04() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        long l1 = f1.length();
        System.out.println(l1);//28
    }
}

File类判断功能的方法

public boolean exists():此File表示的文件夹或目录是否实际存在
public boolean isDirectory():此File表示的是否为目录
public boolean isFile():此File表示的是否为文件

public class Demo04File {
    public static void main(String[] args) {
        show01();
        show02();
    }

    //public boolean exists():此File表示的文件夹或目录是否实际存在
    //用于判断构造方法中的路径是否存在
    //存在返回true 不存在返回false

    private static void show01() {
        //判断存在的绝对路径
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        boolean e1 = f1.exists();
        System.out.println(e1);//true
        //判断不存在的绝对路径
        File f2 = new File("D:\\java\\ceshi\\day01\\b.txt");
        boolean e2 = f2.exists();
        System.out.println(e2);//false
        //判断存在的相对路径
        File f3 = new File("a.txt");
        System.out.println(f3.exists());//true
    }

    //public boolean isDirectory():此File表示的是否为目录
    //  用于判断构造方法中给定的路径是否以文件夹结尾
    //  是:true 否:false
    //public boolean isFile():此File表示的是否为文件
    //  用于判断构造方法中给定的路径是否以文件结尾
    //  是:true 否:false
    //注意:电脑的硬盘中只有文件/文件夹,两个方法是互斥
    //     这两个方法使用前提:路径必须是存在的,否则都返回false
    private static void show02() {
        File f1 = new File("D:\\java\\ceshi\\day01\\a.txt");
        System.out.println(f1.isDirectory());//false
        System.out.println(f1.isFile());//false

    }
}

File类创建删除功能的方法

public boolean createNewFiLe():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete():删除由此FiLe表示的文件或目录。
public boolean mkdir() :创建由此FiLe表示的目录。
public boolean mkdirs():创建由此FiLe表示的目录,包括任何必需但不存在的父目录。

public class Demo05File {
    public static void main(String[] args) throws IOException {
        show01();
        show02();
        show03();
    }

    //public boolean createNewFiLe():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
    //创建问价的路径和名称再构造方法中给出(构造方法的参数)
    //返回值:boolean true:文件不存在,创建文件,返回true
    //               false:文件存在,不会创建,返回false
    //注意:1、此方法只能创建文件,不能创建文件夹
    //     2、创建文件的路径必须存在,否则会抛出异常
    private static void show01() throws IOException {
        //绝对路径创建
        File f1 = new File("D:\\java\\ceshi\\day01\\1.txt");
        boolean b1 = f1.createNewFile();
        System.out.println(b1);//true成功创建了1.txt文件
        //相对路径创建
        File f2 = new File("2.txt");
        System.out.println(f2.createNewFile());
    }
    //public boolean mkdir() :创建由此FiLe表示的目录。只能创建单级文件夹
    //public boolean mkdirs():创建由此FiLe表示的自录,包括任何必需但不存在的父目录。既可以创建单级文件夹也可创建多级空
    //创建文件夹的路径和名称再构造方法中给出(构造方法的参数)
    //返回值:boolean true:文件夹不存在,创建文件,返回true
    //               false:文件夹存在,不会创建,返回false;构造方法中给出的路径不存在也返回false
    //注意:此方法只能创建文件夹,不能创建文件
    private static void show02() {
        //创建单级文件夹
        File f1 = new File("D:\\java\\ceshi\\day01\\aaa");
        boolean b1 = f1.mkdir();
        System.out.println(b1);//true 创建了一个aaa的文件夹
        //创建多级文件夹
        File f2 = new File("D:\\java\\ceshi\\day01\\aaa\\bbb\\ccc");
        boolean b2 = f2.mkdirs();
        System.out.println(b2);//true创建多级文件夹
    }

    //public boolean delete():删除由此FiLe表示的文件或目录。
    //此方法,可以删除构造方法路径中给出的文件/文件夹
    //返回值:boolean
    //      true:文件/文件夹删除成功,返回true
    //      false:文件夹中有内容,不会删除返回false,构造方法中路径不存在false
    //注意:delete方法是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎
    private static void show03() {
        File f1 = new File("2.txt");
        System.out.println(f1.delete());//true成功删除文件2.txt

        File f2 = new File("D:\\java\\ceshi\\day01\\aaa\\bbb");
        System.out.println(f2.delete());//false,因为bbb文件夹中还有文件夹ccc

        File f3 = new File("D:\\java\\ceshi\\day01\\aaa\\ddd");
        System.out.println(f3.delete());//false,没有ddd文件夹
    }
}

FiLe类遍历(文件夹)目录功能

public String[ ] list():返回一个String数组,表示该FiLe目录中的所有子文件或目录。
public File[ ] listFiLes():返回一个FiLe数组,表示该FiLe目录中的所有的子文件或目录。
注意:
List方法和ListFiles方法遍历的是构造方法中给出的目录
如果构造方法中给出的目录的路径不存在,会抛出空指针异常
如果构造方法中给出的路径不是一个目录,也会抛出空指针异常

public class Demo06File {
    public static void main(String[] args) {
        show01();
        show02();
    }

    //public String[ ] list():返回一个String数组,表示该FiLe目录中的所有子文件或目录。
    //遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称存储到一个String类型的数组中
    //也可获取到隐藏的文件夹
    private static void show01() {
        File f1 = new File("D:\\java\\ceshi\\day01");
        String[] arr = f1.list();
        for (String fileName:arr){
            System.out.println(fileName);//1.txt a.txt aaa
        }
    }

    //public File[ ] listFiLes():返回一个FiLe数组,表示该FiLe目录中的所有的子文件或目录。
    //遍历构造方法中给出的目录,会获取目录中所有文件/文件夹,把文件/文件夹封装为File对象,多个File对象存储到File数组中
    private static void show02() {
        File f1 = new File("D:\\java\\ceshi\\day01");
        File[] arr = f1.listFiles();
        for (File fileName:arr){
            System.out.println(fileName);//D:\java\ceshi\day01\1.txt  D:\java\ceshi\day01\a.txt  D:\java\ceshi\day01\aaa
        }
    }
}

递归

概念

方法自己调用自己就是递归

递归的分类

递归分为两种,直接递归和间接递归
直接递归称为方法自身调用自己
间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法

注意事项

递归一定要有条件限制,保证递归能够停止下来,否则会发生栈内存溢出
在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
构造方法:禁止递归
递归的使用前提:
当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归

public class Demo01Recurison {
    public static void main(String[] args) {
        a();
        b(1);
    }

    //递归一定要有条件限制,保证递归能够停止下来,否则会发生栈内存溢出
    private static void a() {
        System.out.println("a方法");
        a();
    }
    //在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
    private static void b(int i) {
        System.out.println(i);
        if (i==1000){
            return;//结束方法
        }
        b(++i);
    }

    //构造方法不能递归
    //编译报错:构造方法是创建对象使用的,一直递归会导致内存中有无数个对象,直接编译报错
    //
    public Demo01Recurison(){
        //Demo01Recurison();
    }


}

在这里插入图片描述

使用递归计算1-n之间的和
public class Demo02Recurison {
    public static void main(String[] args) {
        int s = sum(3);
        System.out.println(s);//6
    }
    //定义一个方法,使用递归计算1-n之间的和
    //1+2+3+...+n
    //n+(n-1)+(n-2)+...+1
    //最大值n,最小值1
    //使用递归必须明确:1、递归的结束条件 获取到1的时候结束
    //              2、递归的目的:获取到下一个被加的数字(n-1)
    public static int sum(int n){
        //获取到1的时候结束
        if(n==1){
            return 1;
        }
        //获取下一个被加的数组(n-1)
        return n + sum(n-1);
    }
}

在这里插入图片描述

递归求阶乘
public class Demo03Recurison {
    public static void main(String[] args) {
        int h = cJ(5);
        System.out.println(h);
    }

    //定义方法使用递归计算阶乘
    //5! = 5*(5-1)*(5-2)*(5-3)*(5-4)
    //递归结束的条件:获取到1的时候结束
    //递归的目的:获取到下一个被乘的数字(n-1)

    public static int cJ(int n){
        //获取到1的时候结束
        if (n==1){
            return 1;
        }
        //获取到下一个被乘的数字(n-1)
        return n * cJ(n-1);
    }
}
打印多级目录
//递归打印多级目录
public class Demo04Recurison {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){
        System.out.println(dir);//输出打印文件夹名称
        File[] files = dir.listFiles();
        for (File f : files) {
            //对遍历得到的File对象f进行判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}
文件搜索
//递归打印多级目录
public class Demo05Recurison {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){
        //System.out.println(dir);//输出打印文件夹名称
        File[] files = dir.listFiles();
        for (File f : files) {
            //对遍历得到的File对象F进项判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                //只要.java结尾的文件
                //1、把File对象f,转换为字符串对象
                //String name = f.getName();//abc.java
                //String path = f.getPath();//D:\\ceshi\\day01\\abc.java
                String s = f.toString();//D:\\ceshi\\day01\\abc.java
                //把字符串转换为小写
                s = s.toLowerCase(Locale.ROOT);
                //2、调用String类中的方法endsWith判断字符串是否是以.java结尾
                boolean b = s.endsWith(".java");
                //3、如果是以.java结尾的文件则输出
                if (b){
                    System.out.println(f);

                }

            }
        }
    }
}

过滤器

使用过滤器来是实现
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器
File[] listFiles(FileFilter filter)
java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器
作用:用来过滤文件(File对象)
抽象方法:用来过滤文件的方法
boolean accept(File pathname)测试指定抽象路径名是否应该包含在某个路径名列表中
参数:File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
File[] listFiles(FilenameFilter filter)
java.io.FilenameFiles接口:实现此接口的类实例可用于过滤器文件名
作用:用于过滤文件名称
抽象方法:用来过滤文件的方法
boolean accept(File dir,String name)测试指定文件是否应该包含在某一文件列表中
参数:File dir:构造方法中传递的被遍历的目录
String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹名称
注意:两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤器的方法accept,在方法中自己定义过滤的规则

使用第一种过滤器

主方法
public class Demo01Filter {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){

        File[] files = dir.listFiles(new FileFiterImpl());//传递过滤器对象
        for (File f : files) {
            //对遍历得到的File对象F进项判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}

使用匿名内部类
public class Demo02Filter {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){

        //传递过滤器对象,使用匿名内部类传递
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
                return pathname.isDirectory() || pathname.getName().toLowerCase(Locale.ROOT).endsWith(".java");
            }
        });
        for (File f : files) {
            //对遍历得到的File对象F进项判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}
重写accept方法
//创建过滤器FileFilter的实现类,重写过滤方法accept,定义过滤规则
public class FileFiterImpl implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        //在此方法中,判断File对象是否是以.java结尾
        //是就返回true,不是就返回false
        //如果pathname是一个文件夹,返回true,继续编辑这个文件夹
        if (pathname.isDirectory()){
            return true;//返回true后会把文件夹也放在File数组中
        }
        return pathname.getName().toLowerCase(Locale.ROOT).endsWith(".java");
    }
}
为什么要重写accept方法的原理

在accept方法中判断传递的文件是否以.java结尾
在这里插入图片描述

使用第二种过滤器

public class Demo02Filter {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){


        File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
                return new File(dir,name).isDirectory() || name.toLowerCase(Locale.ROOT).endsWith(".java");
            }
        });
        for (File f : files) {
            //对遍历得到的File对象F进项判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}

使用Lambda表达式优化匿名内部类
public class Demo02Filter {
    public static void main(String[] args) {
        File file = new File("D:\\java\\ceshi\\day01");
        getAllFile(file);
    }
    //定义一个方法,参数传递File类型目录
    //方法中对目录进行遍历
    public static void getAllFile(File dir){


        //使用Lambda表达式优化匿名内部类(接口中只有一个抽象方法)

        File[] files = dir.listFiles((File d, String name)->{
            //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
            return new File(d,name).isDirectory() || name.toLowerCase(Locale.ROOT).endsWith(".java");

        });


        for (File f : files) {
            //对遍历得到的File对象F进项判断,判断是否是文件夹
            if (f.isDirectory()){
                //f是一个文件夹,则继续遍历这个文件夹
                //getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可
                getAllFile(f);
            }else {
                //f是一个文件,直接打印即可
                System.out.println(f);
            }
        }
    }
}

IO流

在这里插入图片描述

IO字节输出流

	切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象底层传输的始终为二进制数据。

java.io.OutputStream:此抽象类是表示输出字节流的所有类的超类
定义了一些子类共性的成员方法:
public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len):从指定的字节数组写入len字节,从偏移
public abstract void write(int b):将指定的字节输出流。
java.io.FileOutPutStream extends OutputStream
FileOutPutStream:文件字节输出流
作用:把内存中的数据写到硬盘的文件中
构造方法:
FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流
FileOutputStream(File file)创建一个向指定File对象表示的文件中写入数据的文件输出流
参数:写入数据的目的地
String name:目的地是一个文件的路径
File file:目的地是一个文件
构造方法的作用:
1、创建一个FileOutputStream对象
2、会根据构造方法中传递的文件/文件路径,创建一个空的文件
3、会把FileOutputStream对象指向创建好的文件

写入数据的原理(内存–>硬盘)

java程序–>JVM(java虚拟机)–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中

字节输出流的使用步骤(重点)

1、创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2、调用FileOutputStream对象中的方法write,把数据写入到文件中
3、释放资源(流的使用会占用一定的内存,使用完毕要把内存清空,提高程序效率)

public class Demo01OutputStream {
    public static void main(String[] args) throws IOException {
        //1、创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
        FileOutputStream fos = new FileOutputStream("D:\\java\\ceshi\\day01\\a.txt");
        //2、调用FileOutputStream对象中的方法write,把数据写入到文件中
        //public abstract void write(int b):将指定的字节输出流。
        fos.write(97);
        //3、释放资源(流的使用会占用一定的内存,使用完毕要把内存清空,提高程序效率)
        //public void close():关闭此输出流并释放与此流相关联的任何系统资源。
        fos.close();
    }
}

文件存储原理

在这里插入图片描述

字节输出流写多个字节的方法

一次写多个字节的方法
public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len):从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。

public class Demo02OutputStream {
    public static void main(String[] args) throws Exception {
        //1、创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
        FileOutputStream fos = new FileOutputStream(new File("D:\\java\\ceshi\\day01\\b.txt"));
        //2、调用FileOutputStream对象中的方法write,把数据写入到文件中
        //在文件中显示100,写一个字节
        fos.write(49);
        fos.write(48);
        fos.write(48);

        //public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
        //可一次写多个字节:如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
        //               如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)

        byte[] btes = {65,66,67,68,69};
        fos.write(btes);//ABCDE

        //public void write(byte[] b, int off, int len):从指定的字节数组写入len字节,从偏移量off开始输出到此输出流
        //把字节数组的一部分写入到文件中
        fos.write(btes,1,2);//BC

        //写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组
        //byte[] getBytes() 把字符串转换为字节数组
        byte[] bytes = "你好".getBytes();//把你好变为字节数组传递到bytes对象中
        System.out.println(Arrays.toString(bytes));//[-28, -67, -96, -27, -91, -67]
        //utf-8中3个字节是一个字符,GBK中两个字节是一个字符
        fos.write(bytes);

        //释放资源
        fos.close();
    }
}

字节输出流的续写和换行

上面追加在b.txt中的内容都是重新写了之后把之前的b.txt覆盖掉了
追加写/续写:使用俩个参数的构造方法
FiLeOutputStream(String name, booLean append )创建一个向具有指定name的文件中写入数据的输出文件流。
FiLeOutputStream(File fiLe, booLean append))创建一个向指定 FiLe对象表示的文件中写入数据的文件输出流。
构造方法的参数:
String name, File fiLe:写入数据的目的地
boolean append:追加写开关
true:创建对象不会覆盖原文件,继续在文件的末尾追加写数据
false:创建一个新文件,覆盖原文件

换行:写换行符号
windows:\r\n linux:/n mac:/r

public class Demo03OutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\java\\ceshi\\day01\\b.txt",true);
        for (int i = 0; i < 10; i++) {
            fos.write("你好".getBytes(StandardCharsets.UTF_8));
            fos.write("\r\n".getBytes());//"\r\n"也是字符需要转换为字节
        }

        fos.close();
    }


}

IO字节输入流

字节输入流读取字节数据

java.io.InputStream:字节输入流:
此抽象类是表示字节输入流的所有类的超类。
定义了所有子类共性的方法:
int read()从出入流中读取数据的下一个字节
int read()从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
void close()关闭此输入流并释放与该流有关联的所有系统资源
Java.io.FileInputStream extends InputStream
FileInputStream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:FileInputStream(String name)
FileInputStream(File file)
参数:读取文件的数据源
String name:文件的路径
File file:文件
作用:1、创建一个FileInputStream对象
2、会把FileInputStream对象指定构造方法中要读取的文件
读取数据的原理(硬盘–>内存)
java程序–>JVM–>OS–>OS读取数据的方法–>读取文件
字节输入流的使用步骤(重点)
1、创建FileInputStream对象,构造方法中绑定要读取的数据源
2、使用FileInputStream对象中的方法read,读取文件
3、释放资源

public class Dmeo01InputStream {
    public static void main(String[] args) throws Exception {
        //1、创建FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\a.txt");
        //2、使用FileInputStream对象中的方法read,读取文件
        //int read()读取文件中的一个字节并返回,读取到文件的末尾返回-1
        /*int len = fis.read();
        System.out.println(len);//97
        System.out.println(fis.read());//98
        System.out.println(fis.read());//99
        System.out.println(fis.read());//-1读取完成返回-1*/

        //发现以上读取文件是一个重复过程,所以使用循环忧患
        //可是不知文件有多少字节,使用while循环
        //布尔表达式(len = fis.read()) != -1
        //  1、fis.read()读取一个字节
        //  2、len = fis.read()把读取到的字节赋值给变量len
        //  3、(len = fis.read()) != -1判断变量len是否不等于-1
        int len = 0;//记录读取到的字节
        while((len = fis.read()) != -1){
            //System.out.println(len);//97 98 99
            System.out.print((char) len);//输出不换行,并且输出为字符 abc
        }

        //3、释放资源
        fis.close();
    }
}

字节输入流一次读取一个字节/多个字节的原理

在这里插入图片描述

字节输入流一次读取多个字节

字节输入流一次读取多个字节的方法
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
明确两件事情:
1、方法的参数byte[]的作用
起到缓冲作用,存储每次读取到的多个字节
数组的长度定义为1024的整数倍
2、方法的返回值int是什么
每次读取的有效字节个数
String类的构造方法
String(byte[] bytes):把字节数组转为字符串
Strng(byte[],int offset,int length)把字节数组的一部分转换为字符串
offset:数组的开始索引 length:转换的字节个数
使用数组就是一个缓冲原理

public class Dmeo02InputStream {
    public static void main(String[] args) throws Exception {
        //1、创建FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\b.txt");
        //2、使用FileInputStream对象中的方法read读取文件
        //int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
        byte[] bytes = new byte[2];
        int len = fis.read(bytes);
        System.out.println(len);//2
        //System.out.println(Arrays.toString(bytes));//[65, 66]
        System.out.println(new String(bytes));//AB

        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//CD

        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//
        //3、释放资源
        fis.close();

    }
}

代码优化
public class Dmeo02InputStream {
    public static void main(String[] args) throws Exception {
        //1、创建FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\b.txt");
        //2、使用FileInputStream对象中的方法read读取文件
        //int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
        /*byte[] bytes = new byte[2];
        int len = fis.read(bytes);
        System.out.println(len);//2
        //System.out.println(Arrays.toString(bytes));//[65, 66]
        System.out.println(new String(bytes));//AB

        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//CD

        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//*/
        // 发现以上读取是一个重复的过程,可以使用循环优化
        //不知道文件中有多个字节,所以使用while循环
        //while循环结束的条件,读取到-1结束

        byte[] bytes = new byte[1024];//存储读取到的多个字节
        int len = 0;//记录每次读取的有效字节个数
        while((len = fis.read(bytes)) != -1){
            //System.out.println(new String(bytes));//这里转换不能全部转换,因为这个数组定义为1024个字节
            //String(byte[],int offset,int length)把字节数组的一部分转换为字符串
            System.out.println(new String(bytes,0,len));

        }
        //3、释放资源
        fis.close();
    }
}

文件复制案例

package cn.itcast.day15.demo04;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Demo01CopyFile {
    public static void main(String[] args) throws Exception {
        long s = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\a.txt");
        FileOutputStream fos = new FileOutputStream(new File("D:\\java\\ceshi\\day01\\aaa\\b.txt"));

        byte[] bytes = new byte[1024];//存储读取到的多个字节
        int len = 0;//记录每次读取的有效字节个数
        while((len = fis.read(bytes)) != -1){
            fos.write(bytes,0,len);
            System.out.println(new String(bytes,0,len));
        }
        fos.close();
        fis.close();
        long e = System.currentTimeMillis();
        System.out.println("复制共耗时:"+ (e-s) +"毫秒");


    }

}

使用字节流读取中文的问题

使用字节流读取中文文件,GBK占2个字节,UTF-8占用3个字节,不能读取1/3个字符,所以就需要引入字符流

IO字符输入流

java.io.Reader:字符输入流,是字符输入流的最顶层父类,定义了一些共性的成员方法,是一个抽象类
共性的成员方法:
int read()读取单个字符并返回
int read(char[] cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
java.io.FiLeReader extends InputStreamReader extends Reader
FiLeReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FiLeReader(String fiLeName)
FiLeReader(File file)
参数:读取文件的数据源
String fileName:文件的路径
FiLe file:一个文件
FiLeReader构造方法的作用:
1.创建一个FileReader对象
2.会把FileReader对象指向要读取的文件
字符输入流的使用步骤:
1、创建FileReader对象,构造方法中绑定要读取的数据源
2、使用FileReader对象中的方法read读取文件
3、释放资源

public class Demo01Reader {

    public static void main(String[] args) throws Exception {
        //1、创建FileReader对象,构造方法中绑定要读取的数据源
        FileReader fr = new FileReader("D:\\java\\ceshi\\day01\\b.txt");
       /* //2、使用FileReader对象中的方法read读取文件
       int len = 0;
       while((len = fr.read())!=-1){
           System.out.print((char) len);//你好
       }*/

       //int read(char[] cbuf)一次读取多个字符,将字符读入数组。
        char[] cs = new char[1024];//存储读取到的多个字符
        int len = 0;//记录的是每次读取的有效字符个数
        while ((len = fr.read(cs))!=-1){
            //String类的构造方法
            //String(char[] value)把字符数组转换为字符串
            //String(char[] value,int offset,int count)把字符数组的一部分转换为字符串
            //offset数组的开始索引count转换的个数
            System.out.println(new String(cs,0,len));
        }

        //3、释放资源
        fr.close();

    }
}

IO字符输出流

java.io.writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类
共性的成员方法:
void write(int c)写入单个字符。
void write(char[] cbuf)写入字符数组。
abstract void write(char[] cbuf,int off, int len)写入字符数组的某一部分, off数组的开始索引, Len写的字符个数。
void write( String str)写入字符串。
void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引, Len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
java.io.FileWriter extends OutputStreamWriter extends Writer
FiLewriter:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法:
FileWriter(File fiLe)根据给定的File 对象构造一个FiLeWriter 对象。
FiLewriter(String fileName)根据给定的文件名构造一个FileWriter对象。
参数:写入数据的目的地
String fileName:文件的路径
File file:是一个文件
构造方法的作用:
1.会创建一个FileWriter对象
2.会根据构造方法中传递的文件/文件的路径,创建文件
3.会把FiLeWriter对象指向创建好的文件
字符输出流的使用步骤(重点);
1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
2.使用FiLeWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
4.释放资源(会先把内存缓冲区中的数据刷新到文件中)

public class Demo01Writer {
    public static void main(String[] args) throws IOException {
        //1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
        FileWriter fw = new FileWriter("D:\\java\\ceshi\\day01\\1.txt");
        //2.使用FiLeWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
        fw.write(98);
        //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
        fw.flush();
        //4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
        fw.close();


    }
}

flush方法和close方法的区别

flush:刷新缓冲区,流对象还可以继续使用
close:先刷新缓冲区,然后同志系统释放资源,流对象就不能在被使用了

字符输出流写数据的其他方法

void write(char[] cbuf)写入字符数组。
abstract void write(char[] cbuf,int off, int len)写入字符数组的某一部分, off数组的开始索引, Len写的字符个数。
void write( String str)写入字符串。
void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引, Len写的字符个数。

public class Demo02Writer {
    public static void main(String[] args) throws IOException {
        //1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
        FileWriter fw = new FileWriter("D:\\java\\ceshi\\day01\\1.txt");
        //2、void write(char[] cbuf)写入字符数组
        char[] cs = {'a','b','c','d','e','f'};
        fw.write(cs);//abcdef
        //void write(char[] cbuf,int off, int len)写入字符数组的某一部分, off数组的开始索引, Len写的字符个数
        fw.write(cs,1,3);//bcd
        //void write( String str)写入字符串
        fw.write("小甜甜爱蹦蹦蹦");//小甜甜爱蹦蹦蹦
        //void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引, Len写的字符个数
        fw.write("吸烟有害健康",0,2);//吸烟
        fw.close();
    }
}

字符输出流的续写和换行

续写和换行
续写和换行:使用两个参数的构造方法
FileWriter(String filename,boolean append)
FileWriter(File file,boolean append)
参数:String fileName,File file:写入数据的目的地
boolean append:续写开关 true:不创建新的文件覆盖源文件,可以续写 false:创建新的文件覆盖源文件
换行:windows:\r\n linux:/n mac:/r

public class Demo03Writer {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\java\\ceshi\\day01\\1.txt",true);
        for (int i = 0; i < 10; i++) {
            fw.write("HelloWorld" + i + "\r\n");
        }
        fw.close();
    }

}

Properties集合

java.util.Properties集合 extends Hashtable<k,v> implements Map<k,v>
Properties类表示了一个持久的属性集,Properties可保存在流中或者从流中加载
Properties集合是一个唯一和IO流相结合的集合
可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
Properties集合属性列表中每个键值及其对应值都是一个字符串
Properties集合是一个双列集合,key和value默认都是字符串

使用Properties集合存储数据,遍历

使用Properties集合存储数据,遍历取出Properties集合中的数据
Properties集合属性列表中每个键值及其对应值都是一个字符串
Properties集合有一些操作字符串的特有方法
Object setProperty(String key,String value)调用Hashtable的方法put
String getProperty(String key)用指定的键在此属性列表中搜索属性,即通过key找到value
此方法相当于Map集合中的get(key)方法
Set stringPropertyNames()返回此属性列表中的键集,其中该键及其对应值是字符串,此方法相当于Map集合中的keySet

private static void show01() {
        //创建一个Prperties集合对象
        Properties prop = new Properties();
        //使用setProperties往集合中添加数据
        prop.setProperty("Alice","155");
        prop.setProperty("Bob","157");
        prop.setProperty("Mallory","185");

        //使用stringPropertyNames()把Prperties集合中的键取出,存储到一个Set集合中
        Set<String> set = prop.stringPropertyNames();
        //遍历Set集合,取出Properties集合的每一个键
        for (String key : set) {
            //使用getProperty方法通过哦key获取value
            String value = prop.getProperty(key);
            System.out.println(key+"="+value);
        }

Properties集合中的方法store

可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
void store(OutputStream out,String comments)
void store(Writer writer,String comments)
参数:
OutputStream out:字节输出流,不能写入中文
Writer writer:可以写中文
String comments:注释:用来解释说明保存的文件是做什么用的
不能使用中文,会产生乱码,默认是Unicode编码,一般使用“空字符串”
使用步骤:1、创建Properties集合对象,添加数据
2、创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
3、使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
4、释放资源

private static void show02() throws IOException {
        //1、创建Properties集合对象,添加数据
        Properties prop = new Properties();
        //使用setProperties往集合中添加数据
        prop.setProperty("Alice","155");
        prop.setProperty("Bob","157");
        prop.setProperty("Mallory","185");
        //2、创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
        FileWriter fw = new FileWriter("D:\\java\\ceshi\\day01\\c.txt");
        //3、使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
        prop.store(fw,"save data");
        //4、释放资源
        fw.close();

    }
    //这里因为在字节流中读取文件会因为编码方式的不同,中文会出现乱码,建议使用字符流或者英文
    private static void show03() throws IOException {
        //1、创建Properties集合对象,添加数据
        Properties prop = new Properties();
        //使用setProperties往集合中添加数据
        prop.setProperty("Alice","155");
        prop.setProperty("Bob","157");
        prop.setProperty("Mallory","185");
        prop.store(new FileOutputStream("D:\\java\\ceshi\\day01\\d.txt"),"save data");

    }

Properties集合中的方法load

可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputStream inStream)
void load(Reader reader)
参数:InputStream inStream:字节输入流,不能读取含有中文的键值对
Reader reader:字符输入流,能读取含有中文的键值对
使用步骤:
1、创建一个Properties集合对象
2、使用Properties集合对象中的方法load读取保存键值对的文件
3、遍历Properties集合
注意:1、存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
2、存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
3、存储键值对的文件中,键与值都是字符串,不用加引号

 private static void show04() throws IOException {
        //1、创建Properties集合对象,添加数据
        Properties prop = new Properties();
        //2、使用Properties集合对象中的方法load读取保存键值对的文件
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\d.txt");
        prop.load(fis);
        //3、遍历Properties集合
        Set<String> set = prop.stringPropertyNames();
        //遍历Set集合,取出Properties集合的每一个键
        for (String key : set) {
            //使用getProperty方法通过哦key获取value
            String value = prop.getProperty(key);
            System.out.println(key+"="+value);
        }

    }

缓冲流

缓冲流的原理

在这里插入图片描述

BufferedOutputStream字节缓冲输出流

java.io.BufferedOutputStream extends OutputStream
BufferedOutputStream:字节缓冲输出流
继承自父类的共性方法
public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len):从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。
public abstract void write(int b):将指定的字节输出流。
构造方法:
BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
BufferedOutputStream(OutputStream out,int size)创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
参数:OutputStream out:字节输出流
我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤:1、创建FileOutputStream对象,构造方法中绑定要输出的目的地
2、创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率
3、使用BufferedOutputStream对象中的方法writer,把数据写入到内部缓冲区中
4、使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中
5、释放资源(会先调用flush方法刷新数据,第4步可以省略)

public class Demo02BufferedOutputStream {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("D:\\java\\ceshi\\day01\\e.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("甜是真的甜".getBytes(StandardCharsets.UTF_8));
        bos.flush();
        bos.close();
    }
}

BufferedInputStream字节缓冲输入流

java.io.BufferedInputStream extends InputStream
BufferedInputStream:字节缓冲流
继承自父类的成员方法:
int read()从出入流中读取数据的下一个字节
int read()从输入流中读取一数量的字节,并将其存储在缓冲区数组b中
void close()关闭此输入流并释放与该流有关联的所有系统资源
构造方法:BufferedInputStream(InputStream in)创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用
BufferedInputStream(InputStream in,int size)创建具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流in,以便将来使用
参数:InputStream in:字节输入流
我们可以传递FileInputStream,缓冲区会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率
int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤:1、创建一个FileInputStream对象,构造方法中绑定要读取的数据源
2、创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
3、使用BufferedInputStream对象中的read,读取文件
4、释放资源
5、关闭资源

public class Demo02BufferedInputStream {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("D:\\java\\ceshi\\day01\\a.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        /*int len = 0;
        while((len = bis.read()) != -1){
            System.out.println((char) len);
        }*/
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = bis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }


        bis.close();
    }


}

BufferedWriter字符缓冲输出流

java.io.BufferedWriter extends Writer
BufferedWriter:字符缓冲输出流
继承自父类的共性成员方法:
void write(int c)写入单个字符。
void write(char[] cbuf)写入字符数组。
abstract void write(char[] cbuf,int off, int len)写入字符数组的某一部分, off数组的开始索引, Len写的字符个数。
void write( String str)写入字符串。
void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引, Len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
构造方法:
1、BufferedWriter(Writer out) 创建一个使用默认大小缓冲区的缓冲字符输出流
2、BufferedWriter(Writer out,int sz) 创建一个使用给定大小输出缓冲区的新缓冲区字符输出流
参数:Writer out:字符输出流
可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率
int sz:指定缓冲区的大小,不写默认大小
特有成员方法:void newLine()写一个行分隔符。会根据不同的操作系统获取不同的行分隔符
使用步骤:1、创建字符缓冲输出流对象,构造方法中传递字符输出流
2、调用字符缓冲输出流中的方法writer,把数据写入到内存缓冲区中
3、调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
4、释放资源

public class Demo03BufferedWriter {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\java\\ceshi\\day01\\f.txt"));
        for (int i = 0; i < 10; i++) {
            bw.write("吸烟有害健康!");
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }
}

BufferedReader字符缓冲输入流

java.io.BufferedReader extends Reader
继承自父类的共性成员方法:
int read()读取单个字符并返回
int read(char[] cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
构造方法:
BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in,int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流
参数:Reader in:字符输入流
可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高FileReader的读取效率
特有的成员方法:
String readLine()读取一个文本行,读取一行数据
行的终止符号:通过下列字符之一即可认为某行已将终止:(’\n’)、回车(’\r’)或回车后直接跟着换行(\r\n)
返回值:包含该行内容的字符串,不包含任何终止符,如果已经到达流末尾,则返回null
使用步骤:1、创建字符缓冲输入流对象,构造方法中传递字符输入流
2、使用字符缓冲输入流对象中的方法read/readline读取文本
3、释放资源

public class Demo03BufferedReader {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader("D:\\java\\ceshi\\day01\\f.txt"));
        char[] cs = new char[1024];
        int len = 0;
        while((len = br.read(cs)) != -1 ){
            System.out.println(new String(cs,0,len));

        }
        br.read();
        br.close();
    }
}

转换流

字符编码和字符集

编码:字符->字节
解码:字节->字符

OutputStreamWriter

java.io.OutputStreamWriter extends Writer
OutputStreamWriter:字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编码成字节
继承父类的共性方法:
void write(int c)写入单个字符。
void write(char[] cbuf)写入字符数组。
abstract void write(char[] cbuf,int off, int len)写入字符数组的某一部分, off数组的开始索引, Len写的字符个数。
void write( String str)写入字符串。
void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引, Len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
构造方法:
OutputStreamWriter(OutputStream out)创建使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out,String charsetName)创建使用指定字符集的OutputStreamWriter
参数:OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
String charsetName:指定的编码表名称,不区分大小写,可以是UTF-8/utf-8,不指定默认使用utf-8
使用步骤:
1、创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
2、使用OutputStreamWriter对象中的方法writer,把字符转换为字节存储缓冲区中(编码)
3、使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
4、释放资源

public class Demo02OutputStreamWriter {
    public static void main(String[] args) throws Exception {
        //writer_utf_8();
        writer_gbk();

    }


    //使用转换流OutputStreamWriter写utf-8格式的文件
    //
    private static void writer_utf_8() throws Exception {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\java\\ceshi\\day01\\a.txt"),"utf-8");
        osw.write("你好");
        osw.flush();
        osw.close();

    }

    private static void writer_gbk() throws Exception {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\java\\ceshi\\day01\\a.txt"),"gbk");
        osw.write("你好a");
        osw.flush();
    }
}

InputStreamReader

java.io.InputStreamReader extends Reader
InputStreamReader:是字节流通向字符流的桥梁,它使用指定的charset,读取字节并将其解码为字符
继承自父类的共性成员方法:
int read()读取单个字符并返回
int read(char[] cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
构造方法:
1、InputStreamReader(InputStream in)创建一个使用默认字符集的InputStreamReader
2、InputStreamReader(InputStream in,String charsetName)创建使用指定字符集的InputStreamReader
参数:InputStream in:字节输入流用来读取文件中保存的字节
String charsetName:指定的编码表名称,不区分大小写
使用步骤:
1、创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
2、使用InputStreamReader对象中的方法read读取文件
3、释放资源
注意事项:构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码

public class Demo03InputStreamReader {
    public static void main(String[] args) throws Exception {
        writer_utf_8();

    }

    private static void writer_utf_8() throws Exception {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\java\\ceshi\\day01\\a.txt"),"gbk");
        int len = 0;
        while((len = isr.read())!=-1){
            System.out.println((char) len);
        }
        isr.close();
    }
}

序列化流

序列化和反序列化

在这里插入图片描述

ObjectOutputStream:对象的序列化流

java.io.ObjectOutputStream extends OutputStream
ObjectOutputStream:对象的序列化流
作用:把对象以流的方式写入到文件中保存
构造方法:ObjectOutputStream(OutputStream out)创建写入指定OutputStream的ObjectOutputStream
参数:OutputStream out:字节输出流
特有的成员方法:
void writeObject(Object obj)将指定的对象写入ObjectOutputStream
使用步骤:
1、创建一个ObjectOutputStream对象,构造方法中传递字节输出流
2、使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
3、释放资源
序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常
类通过实现java.io.Serializable 接口启用其序列化功能,未实现此接口的类将无法使其任何状态序列化或反序列化
Serializable接口也叫标记型接口
要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记
当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记
有:就可以序列化和反序列化 没有:就会抛出NotSerializableException异常

public class Demo01ObjectOutputStream {
    public static void main(String[] args) throws Exception {
        //1、创建一个ObjectOutputStream对象,构造方法中传递字节输出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\java\\ceshi\\day01\\Person.txt"));
        //2、使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
        oos.writeObject(new Person("哈哈哈",18));
        // 3、释放资源
        oos.close();
    }
}
public class Person implements Serializable {
    private String name;
    private int age;

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

InputStream:对象的反序列化流

java.io.ObjectInputStream extends InputStream
InputStream:对象的反序列化流
作用:把文件中保存的对象,以流的方式读取出来使用
构造方法:ObjectInputStream(InputStream in)
创建从指定InputStream读取的ObjectInputStream
参数:InputStream in:字节输入流
特有的成员方法:Object readObject() 从ObjectInputStream读取对象
使用步骤:
1、创建ObjectInputStream对象,构造方法中传递字节输入流
2、使用ObjectInputStream对象中的方法readObject()读取保存对象的文件
3、释放资源
4、使用读取出来的文件(打印)
readObject()方法声明抛出了ClassNotFoundException异常(class文件找不到异常)
当不存在对象的class文件时抛出此异常
反序列化的前提:
1、类必须实现Serializable
2、必须存在类对应的class文件

public class Demo02ObjectInputStream {
    public static void main(String[] args) throws Exception {
        // 1、创建ObjectInputStream对象,构造方法中传递字节输入流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\java\\ceshi\\day01\\Person.txt"));
        //2、使用ObjectInputStream对象中的方法readObject()读取保存对象的文件
        Object o = ois.readObject();
        //3、释放资源
        ois.close();
        //4、使用读取出来的文件(打印)
        System.out.println(o);//Person{name='哈哈哈', age=18}
        //强转为Person类型
        Person p = (Person) o;
        System.out.println(p.getName()+p.getAge());
    }
}

transient关键字_瞬态关键字

static关键字:静态关键字
静态优先于非静态加载到内存中(静态优先于对象进入到内存中)
被static修饰的成员变量不能被序列化的,序列化的都是对象
transient关键字:瞬态关键字
被transient修饰成员变量,不能被序列化
如果需要不被序列化,而且非静态就可用transient

InvalidClassException异常

例如:在Person中我们将age的权限改为public ,直接进行反序列化。因为更改了以后其class文件已经被更改,所以就会抛出一个InvalidClassException异常,因为序列号发生了冲突
在这里插入图片描述
自动生成serialVersionUID
Preferences -> Inspections -> Serialization issues -> Serialization class without ‘serialVersionUID’ 打上勾
然后在类的名称上Alt+Enter就会自动生成serialVersionUID

import java.io.Serial;
import java.io.Serializable;

public class Person implements Serializable {



    @Serial
    private static final long serialVersionUID = -7696353887086844926L;
    private String name;
    private int age;

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

序列化集合案例

import java.io.*;
import java.util.ArrayList;

public class Demo01Test {
    public static void main(String[] args) throws Exception {
        //定义一个存储Person对象的ArrayList集合
        ArrayList<Person> list = new ArrayList<>();
        //往ArrayList集合中存储Person
        list.add(new Person("小甜甜",18));
        list.add(new Person("武哈哈",23));
        list.add(new Person("杨蛋蛋",22));
        list.add(new Person("赵鱼鱼",22));
        //创建一个序列化流ObjectOutputStream对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\java\\ceshi\\day01\\2.txt"));
        //使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化
        oos.writeObject(list);
        //创建一个反序列化ObjectInputStream对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\java\\ceshi\\day01\\2.txt"));
        //使用ObjectInputStream对象中的方法readObject()读取文件中保存的集合
        Object o = ois.readObject();
        //把Object类型的集合转换为ArrayList类型
        ArrayList<Person> list1 = (ArrayList<Person>) o;
        //遍历ArrayList
        for (Person p : list1) {
            System.out.println(p);
        }
        //释放资源
        oos.close();
        ois.close();
    }

}

打印流

java.io.PrintStream:打印流
PrintStream 为其他输出流添加了功能,使它们能方便打印各种数据值表示形式
PrintStream特点:
1、只负责数据的输出,不负责数据的读取
2、与其他输出流不同,PrintStream永远不会抛出IoException
3、有特有的方法,print,println
void print(任意类型的值)
void println(任意类型的值并换行)
构造方法:
PrintStream(File file):输出的目的地是一个文件
PrintStream(OutputStream out):输出的目的地是一个字符输出流
PrintStream(String fileName):输出的目的地是一个文件路径
PrintStream extends OutputStream
继承自父类的共性方法
public void close():关闭此输出流并释放与此流相关联的任何系统资源。
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len):从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。
public abstract void write(int b):将指定的字节输出流。
注意事项:如果使用继承自父类的writer方法写数据,那么查看数据的时候会查询编码表97->a
如果使用自己特有的方法print,println方法写数据,写的数据原样输出97->97

public class Demo01PrintStream {
    public static void main(String[] args) throws Exception {
        //创建打印流PrintStream对象,构造方法中绑定要输出的目的地
        PrintStream ps = new PrintStream("D:\\java\\ceshi\\day01\\3.txt");
        //如果使用继承自父类的writer方法写数据,那么查看数据的时候会查询编码表97->a
        ps.write(97);//a
        //如果使用自己特有的方法print,println方法写数据,写的数据原样输出97->97
        ps.println(97);//97 可输出任意的字符类型
        ps.close();

    }
}

打印输出语句的目的地

可以改变输出语句的目的地(打印流的流向)
输出语句,默认在控制台输出
使用System类中setOut方法改变输出语句的目的地为参数传递的打印流的目的地
static void setOut(PrintStream out)重新分配标准输出流

public class Demo02PrintStream {
    public static void main(String[] args) throws Exception {
        System.out.println("这是在控制台输出的!");
        PrintStream ps = new PrintStream("D:\\java\\ceshi\\day01\\4.txt");
        System.setOut(ps);//方法改变输出语句的目的地为参数传递的打印流的目的地
        System.out.println("这是在打印流的目的地中输出!");
        ps.close();
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:40:39  更:2021-08-02 10:41:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/3 14:33:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码