3/20day15_File类_递归_IO流_字节流

复习

能够说出File对象的创建方式
    public File(String path);
    public File(String parent,String child);    
    public File(File file,String child);    
能够使用File类常用方法
    获取方法 getPath getAbsolutepath getName length
    判断方法 exists isFile isDirectory
    创建方法 createNewFile mkdir mkdirs
    删除方法 delete 
能够遍历文件夹
    遍历文件夹方法 list listFiles
能够辨别相对路径和绝对路径【重点】
    绝对路径: 以盘符开头的路径 C:\\windows\\data\\1.txt
    相对路径: 相当于当前项目的根目录 1.txt 表示 当前项目根目录下的1.txt
   
能够解释递归的含义
    方法内部调用方法本身(自己调自己)    
能够使用递归的方式计算5的阶乘(了解)
能够说出使用递归会内存溢出隐患的原因
    递归不断调用方法,方法不断入栈,栈内存就会溢出!!!     
能够说出IO流的分类和功能
   输入流 : 读数据
   输出流 : 写数据   
       
   字节流 : 数据是以字节为单位
   字符流 : 数据是以字符为单位
       
能够使用字节输出流写出数据到文件
       FileOutputStream类
            write(int b);
            write(byte[] bs);
            write(byte[] bs,int startIndex,int len);
能够使用字节输入流读取数据到程序
        FileInputStream类
            int read();
            int read(byte[] bs);
能够理解读取数据read(byte[])方法的原理【掌握】
能够使用字节流完成文件的复制

今日内容

  • File类
  • 递归
  • IO流
  • 字节流

File类

File类的作用

File类可以表示文件或者文件夹(File类的对象,可以用来表示一个文件或者文件夹)

File类的构造

public File(String path);
三种构造方式:

 public static void main(String[] args) {
        //构造方法1
        File f1= new File("G:\\1_study\\2_手册\\jdk api 1.8.CHM");
        //构造方法2
        File f2 = new File("G:\\1_study\\2_手册", "jdk api 1.8.CHM");
        //构造方法3
        File parent = new File("G:\\1_study\\2_手册");
        File f3 = new File(parent, "jdk api 1.8.CHM");
    }

File类的获取方法

  • public String getAbsolutePath() :返回此File的绝对路径名字符串。(绝对路径指从哪个盘符开始)
  • public String getPath() :将此File转换为路径名字符串。
  • public String getName() :返回由此File表示的文件或目录的名称
  • public long length() :返回由此File表示的文件的大小(单位是字节)。 不能获取目录(文件夹)的大小,返回的是个不确定值。

相对路径和绝对路径

  • 绝对路径: 是指从盘符开始到文件,这是一个完整的路径。
    如:"G:\1_study\2_手册\jdk api 1.8.CHM"
  • 相对路径: 从当前项目根目录为起始路径(不含项目目录),这是一个便捷的路径,开发中经常使用。
    如:"day15\day15.iml"

File类的判断方法

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

File类的创建删除方法

  • public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
  • public boolean mkdir() :创建由此File表示的目录(创建单级文件夹)。
  • public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录(创建双级文件夹)。
  • public boolean delete():删除由此File表示的文件或目录。(delete方法,如果此File表示目录,则目录必须为空才能删除。)

目录的遍历 (必须由目录对象调用该方法)

  • public String[] list() :返回一个String数组,表示该File目录中的所有(直接)子文件或目录。
  • public File[] listFiles() :返回一个File对象数组,表示该File目录中的所有的(直接)子文件或目录。(file对象是不仅有名字,还有其名字, 既然返回是个对象组, 可以使用对象调方法)

递归

递归概念

  • 递归:指在当前方法内调用自己的这种现象。
public static void a(){
    a();
}
  • 无限递归(死递归)会出现错误,栈溢出

老师图解

如果要使用递归,必须保证递归有出口(结束的条件),就算有结束出口, 但是在结束之前,也有可能会有栈溢出.

  • 使用递归三步骤
    1.定义一个方法
    2.找规律,调用自己
    3.让递归有出口

递归求和案例(开发中不要用递归)

  • 代码演示
    public static void main(String[] args) {
        System.out.println(getSum(10));
    }

    public static int getSum(int n) {
        if (n == 1) {
            return 1;
        }
       return getSum(n-1)+n;
    }
  • 图解求和递归

递归求阶案例

  • 代码案例
public class DiGuiDemo {
    //计算n的阶乘,使用递归完成
    public static void main(String[] args) {
        int n = 3;
        // 调用求阶乘的方法
        int value = getValue(n);
        // 输出结果
        System.out.println("阶乘为:"+ value);
    }
    /*
      通过递归算法实现.
      参数列表:int 
      返回值类型: int 
    */
    public static int getValue(int n) {
        // 1的阶乘为1
        if (n == 1) {
            return 1;
        }
        /*
          n不为1时,方法返回 n! = n*(n-1)!
          递归调用getValue方法
        */
        return n * getValue(n - 1);
    }
}

文件搜索代码演示

public class DiGuiDemo3 {
    public static void main(String[] args) {
        // 创建File对象
        File dir  = new File("D:\\aaa");
        // 调用打印目录方法
        printDir(dir);
    }
 
    public static void printDir(File dir) {
        // 获取子文件和目录
        File[] files = dir.listFiles();
        
        // 循环打印
        for (File file : files) {
            if (file.isFile()) {
                // 是文件,判断文件名并输出文件绝对路径
                if (file.getName().endsWith(".java")) {
                    System.out.println("文件名:" + file.getAbsolutePath
                }
            } else {
                // 是目录,继续遍历,形成递归
                printDir(file);
            }
        }
    }
}

IO流

IO流的概述

  • 概念(Java中是以内存为基准)
    I: Input 输入流,数据从外部设备到程序中,读数据
    O: Output 输出流 , 数据从程序到外部设备,写数据
    即流向内存是输入流(读流),流出内存的输出流(写流)。
    Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
  • 图解


IO流的分类

  • 根据流方向来分类

    • 输入流
    • 输出流
  • 根绝流中操作的数据类型分类:

    • 字节流
    • 字符流
  • 两种分类综合:

    • 字节输入流
    • 字节输出流
    • 字符输入流
    • 字符输出流

Java中的IO四大流

  • 字节输入流: InputStream(这是其顶层父类,为抽象类)
  • 字节输出流: OutputStream(这是其顶层父类,为抽象类)
  • 字符输入流: Reader(这是其顶层父类,为抽象类)
  • 字符输出流: Writer(这是其顶层父类,为抽象类)


tips: Java中的所有流都会是以上四个流中某一个的子类, 具体流的命名规范为: 功能名+父类名 比如: FileWriter 向文件中写出字符为单位的数据

字节流

万物皆对象和IO流一切皆字节

万物皆对象: 现实生活中的任何东西, 在Java中都可以使用一个对象来表示;
IO流一切皆字节: 电脑中所有数据, 都是由字节组成(二进制组成);在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

字节输出流 [OutputStream] (以字节写入,写的是ASCLL码值)

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了
字节输出流的基本共性功能方法。

  • 顶层父类: OutputStream(抽象类)
  • 共性方法:
    • public void close(): 关闭此流, 释放资源
    • public void fluse(): 刷新缓冲区
    • public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
    • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开
      始输出到此输出流。
    • public abstract void write(int b) :将指定的字节输出流。

FileOutputStream类的使用(是OutputStream的子类)

  • FileOutputStream类概述

    • OutputStream 有很多子类,FileOutputStream类是OutputStream的其中一个子类
    • java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。
  • 构造方法:
    public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
    public FileOutputStream(String path) : 创建文件输出流以指定的名称写入文件。
    构造方法注意
    当使用构造方法创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。如果不想在有这个文件情况下, 不清空文件数据, 使用构造方法public FileOutputStream(File file, boolean append)第二个参数表示是否追加, 追加写true

  • FileOutputStream三个写数据方法(实现的其父类方法)

        FileOutputStream fos = new FileOutputStream("1.txt");
        byte[] kongGe = "\r\n".getBytes();
        fos.write(97);
        fos.write(kongGe);
        fos.write(57);
        fos.write(kongGe);
        byte[] bs = {97,98,99,100};
        fos.write(bs);
        fos.write(kongGe);
        byte[] bytes = "HelloWorld".getBytes();
        fos.write(bytes);
        fos.write(kongGe);
        fos.write(bs,1,2);
        fos.write(kongGe);
  • 换行(向文件中写入换行符号)
    回车符 \r 和换行符 \n :
    回车符:回到一行的开头(return)。
    换行符:下一行(newline)。
    系统中的换行:
    Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
    Unix系统里,每行结尾只有 换行 ,即 \n ;
    Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。

  • close 和 flush
    public void flush() 对字节输出流无用
    public void close() 关闭流, 释放资源
    流一旦使用完毕, 需要关闭, 可以另其他程序使用该文件

字节输入流[InputStream]

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输
入流的基本共性功能方法。

  • 顶层父类: InputSteam(抽象类)

  • 共性方法:

    • public void close():关闭此输入流并释放与此流相关联的任何系统资源。
    • public abstract int read() : 从输入流读取数据的下一个字节. 一次读取一个字节.
    • public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。返回值表示实际读取的字节个数

FileInputStream 类 (是InputStream的子类)[重点]

java.io.FileInputStream 类是文件输入流,从文件中读取字节。

  • 构造方法

    • public FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的文件对象 file命名。
    • public FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
    • 构造方法注意
      创建了文件输入流对象, 如果文件存在,继续执行操作;如果文件不存在, 报错
  • FileInputStream 类读取数据方法(使用其父类InputStream的方法)[重点]

  1. read()方法
    返回值为读取的一个字节, 如果为空字节, 则返回值为-1;
    读取一个字节代码演示
        FileInputStream fis = new FileInputStream("1.txt");
        //  FileInputStream fis = new FileInputStream(new File("2.txt"))
        //int b = fis.read();
        //System.out.println((char) b);
        //========一次读取一个字节的标准循环==========
        int b = 0;
        while ((b = fis.read()) != -1) {
            System.out.println((char) b);
        }
  1. read (byte[] bs)方法
    底层是读取到数组长度个字节后, 会放到创建好的数组中, 如果最后不够了数组长度个字节, 则还会有上一次读取字节在数组中未消除.可以使用String的重载构造
    图解
    一次读取字节数组长度个字节代码演示
        byte[] bs = new byte[4];//实际开发中 , 一般1024,或者其整数倍
        int len = 0;
        while ((len = fis.read(bs)) != -1) {
            System.out.println(new String(bs,0,len));//String的重载方法,第一个参数为需要转换的byte数组对象, 第二个参数为开始索引, 第三个为需要转换的长度
        }

字节流练习:图片复制

  • 图解


  • 代码演示

        FileInputStream fis = new FileInputStream("2.png");
        FileOutputStream fos = new FileOutputStream("copy2.png");

        byte[] bytes = new byte[1024];
        int len =0;
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }

        fis.close();
        fos.close();

今日总结

能够说出File对象的创建方式
    public File(String path);
    public File(String parent,String child);    
    public File(File file,String child);    
能够使用File类常用方法
    获取方法 getPath getAbsolutepath getName length
    判断方法 exists isFile isDirectory
    创建方法 createNewFile mkdir mkdirs
    删除方法 delete 
能够遍历文件夹
    遍历文件夹方法 list listFiles
能够辨别相对路径和绝对路径【重点】
    绝对路径: 以盘符开头的路径 C:\\windows\\data\\1.txt
    相对路径: 相当于当前项目的根目录 1.txt 表示 当前项目根目录下的1.txt
   
能够解释递归的含义
    方法内部调用方法本身(自己调自己)    
能够使用递归的方式计算5的阶乘(了解)
能够说出使用递归会内存溢出隐患的原因
    递归不断调用方法,方法不断入栈,栈内存就会溢出!!!     
能够说出IO流的分类和功能
   输入流 : 读数据
   输出流 : 写数据   
       
   字节流 : 数据是以字节为单位
   字符流 : 数据是以字符为单位
       
能够使用字节输出流写出数据到文件
       FileOutputStream类
            write(int b);
            write(byte[] bs);
            write(byte[] bs,int startIndex,int len);
能够使用字节输入流读取数据到程序
        FileInputStream类
            int read();
            int read(byte[] bs);
能够理解读取数据read(byte[])方法的原理【掌握】
能够使用字节流完成文件的复制
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容