所有的文档和源代码都开源在GitHub: https://github.com/kun213/DailyCode上了。希望我们可以一起加油,一起学习,一起交流。

day11【IO流】

今日学习内容-2020.10.10

@

一、File类

1、能够说出File对象的创建方式

File类的构造方法

  • public File(String pathname) ` :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • public File(String parent,String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

代码举例:

/**
 * File类构造方法
 */

public class FileDemo {
    public static void main(String[] args) {
        method_3();
    }
    /**
     * File类构造方法
     *   File(File parent,String child)传递File类型的父路径,和字符串的子路径
     *   第一个参数是File对象
     */
    public static void method_3(){
        File parent = new File("E:\JavaEE\IdeaProjects");
        File file = new File(parent,"basic-code");
        System.out.println(file);
    }

    /**
     * File类构造方法
     *  File(String parent,String child)传递字符串的父路径,和字符串的子路径
     *  程序中,分的越开越好
     *  单独操作父路径,单独操作子路径
     */
    public static void method_2(){
        File file = new File("E:\JavaEE\IdeaProjects","basic-code");
        System.out.println(file);
    }

    /**
     * File类构造方法
     *   File(String path)传递字符串的路径
     */
    public static void method_1(){
        File file = new File("E:\JavaEE\IdeaProjects\basic-code");
        System.out.println(file);
    }
}

注意

  1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

2、能够使用File类常用方法

File类的获取方法

  • public String getAbsolutePath() :返回此File的绝对路径名字符串。
  • public String getPath() :将此File转换为路径名字符串。
  • public String getName() :返回由此File表示的文件或目录的名称。
  • public long length() :返回由此File表示的文件的长度。
  • public File getParentFile()返回由此File表示的文件或目录的父目录,如果没有父目录,返回null。

代码举例:

/**
 * File类的获取方法
 *   基本上都是get开头
 */
public class FileDemo {
    public static void main(String[] args) {
            method_5();
    }
    /**
     *  String getPath() 将构造方法中的路径,转成字符串
     */
    public static void method_5(){
        File file = new File("E:\JavaEE\IdeaProjects\basic-code");
        String path = file.getPath();
        System.out.println(path.toString());
    }

    /**
     *  File getAbsoluteFile() 返回File构造方法中路径的绝对路径形式
     *  返回值是File对象
     *
     *  注意: 直接传递文件名,或者文件夹名
     *  获取到的绝对路径,将从IDEA的工程下计算
     */
    public static void method_4(){
        File file = new File("1.txt");
        File abso = file.getAbsoluteFile();
        System.out.println(abso);
    }

    /**
     * long length() 获取File构造方法中路径表示的文件的字节数
     */
    public static void method_3(){
      File file = new File("E:\开始学习的Java笔记和代码\测试io\1.txt");
        long l = file.length();
        System.out.println(l);
    }
    /**
     * File getParentFile()  获取,构造方法中封装的路径的父路径
     * 上一级文件夹
     * 方法的返回值是File对象,可以方法调用链
     * 如果此路径名没有父目录,则返回 null。
     */
    public static void method_2(){
        File file = new File("E:\JavaEE\IdeaProjects\basic-code");
        File parent = file.getParentFile().getParentFile();//方法调用链
        System.out.println(parent);
    }
    /**
     * String getName() 返回名字
     * 获取了,构造方法中封装路径,最后的名称
     * 名称可能是文件夹名,可能是文件名
     */
    public static void method_1(){
        File file = new File("E:\JavaEE\IdeaProjects\basic-code");
        String name = file.getName();
        System.out.println(name);
    }
}

3、能够辨别相对路径和绝对路径

  • 绝对路径:从盘符开始的路径,这是一个完整的路径,绝对路径具有唯一性。
  • 相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
public static void main(String[] args) {
    // D盘下的bbb.java文件
    File f = new File("D:\bbb.java");
    System.out.println(f.getAbsolutePath());

    // 项目下的bbb.java文件
    File f2 = new File("bbb.java");
    System.out.println(f2.getAbsolutePath());
}

4、能够遍历文件夹

  • public File[] listFiles()返回一个File数组,表示该File目录中的所有的子文件或目录、
  • public File[] listFiles(FileFilter filter)返回一个File数组,表示该File目录中的所有的子文件或目录,filter是文件过滤器,可以过滤不需要的文件。
public static void main(String[] args) {
    File dir = new File("d:\java_code");
    //获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
    File[] files = dir.listFiles();
    for (File file : files) {
    	System.out.println(file);
    }
}

FileFilter接口

文件过滤器接口,此接口的实现类可以传递给方法listFiles(),实现文件的过滤功能

FileFilter接口方法:

public boolean accept(File path):方法参数就是listFiles()方法获取到的文件或者目录的路径。如果方法返回true,表示需要此路径,否则此路径将被忽略。

遍历目录,获取所有的Java文件

public static void main(String[] args){
    File dir = new File("d:\demo");
    File[] files = dir.listFiles(new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        //判断如果获取到的是目录,直接放行
        if(pathname.isDirectory())
        return true;
        //获取路径中的文件名,判断是否java结尾,是就返回true
        //.toLowerCase是String 中的所有字符都转换为小写
        return pathname.getName().toLowerCase().endsWith("java");
      }
    });
    for(File file : files){
    	System.out.println(file);
    }
}

二、方法递归

1、能够解释递归的含义

/**
 * 方法的递归调用: 编写程序上一个手段
 * 方法自己调用自己,具有方法语言,都可以使用递归
 * 解决问题:
 *   目录遍历案例,功能是确定的,就是制定目录进行遍历
 *   遍历的目录,每次可能不同
 *
 *   功能的计算主体明确,计算中的参数每次是变化
 *
 *   方法自身调用注意事项:
 *     1: 不能是死递归,方法不停的进栈,不会出去,内存满了,溢出
 *     2: 递归一定要有出口,能结束.但是如果进栈的方法过多也不可以
 *
 */

2、能够使用递归的方式计算5的阶乘

分析:分析:n的阶乘:n! = n * (n-1) ... 3 * 2 * 1

实现代码:

public class JieChengDemo {
    public static void main(String[] args) {
        int jieCheng = getJieCheng(5);
        System.out.println(jieCheng);
    }
    /**
    通过递归算法实现.
    参数列表:int
    返回值类型: int
     */
    public static int getJieCheng(int num){
         /*
        num为1时,方法返回1,
        相当于是方法的出口,num总有是1的情况
           */
        if (num == 1){
            return 1;
        }else {
             /*
            num不为1时,方法返回 num +(num-1)的累和
            递归调用getJieCheng方法
              */
            return num * getJieCheng(num-1);
        }
    }

1~N递归求和的代码执行图解:

注意:递归一定要有条件限定,保证递归能够停止下来,否则就是死递归。递归次数不要太多,否则会发生栈内存溢出,会抛出StackOverflowError错误。

3、能够说出使用递归会内存溢出隐患的原因

函数调用的参数是通过栈空间来传递的,在调用过程中会占用线程的栈资源。

递归调用只有走到最后的结束点后函数才能依次退出,而未到达最后的结束点之前,占用的栈空间一直没有释放,如果递归调用次数过多,就可能导致占用的栈资源超过线程的最大值,从而导致栈溢出,导致程序的异常退出。

三、IO流

1、能够说出IO流的分类和功能

根据数据的流向分为:输入流输出流

  • 输入流 :把数据从其他设备上读取到内存中的流。
  • 输出流 :把数据从内存 中写出到其他设备上的流。

格局数据的类型分为:字节流字符流

  • 字节流 :以字节为单位,读写数据的流。
  • 字符流 :以字符为单位,读写数据的流。

四、字节流

使用字节流可以进行任何文件的复制,因为字节流操作的是组成文件的最小单元-字节。

复制原理图解:

代码实现

/**
 * 字节流复制文件,任意文件
 * 不能是文件夹
 */ 
public static void main(String[] args) throws IOException {
     // 1.创建流对象
     // 1.1 指定数据源
     FileInputStream fis = new FileInputStream("D:\test.jpg");
     // 1.2 指定目的地
     FileOutputStream fos = new FileOutputStream("test_copy.jpg");

     // 2.读写数据
     // 2.1 定义数组
     byte[] b = new byte[1024];
     // 2.2 定义长度
     int len;
     // 2.3 循环读取
     while ((len = fis.read(b))!=-1) {
         // 2.4 写出数据
         fos.write(b, 0 , len);
     }

     // 3.关闭资源
     fos.close();
     fis.close();
}

五、字节缓冲流

1、能够使用字节流缓冲流复制文件

缓冲流:针对基础流对象进行高效处理的流对象。或者为基础流增加功能。

字节缓冲流BufferedInputStreamBufferedOutputStream

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

构造方法

  • public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
  • public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流。
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));

注意:在使用缓冲流时,必须传递基础流。

代码实现:缓冲流+数组方式:

public static void main(String[] args) throws FileNotFoundException {
    // 记录开始时间
    long start = System.currentTimeMillis();
    // 创建流对象
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk8.exe"));
    BufferedOutputStream bos = new BufferedOutputStream(new           FileOutputStream("copy.exe"));
    
    // 读写数据
    int len = 0;
    byte[] bytes = new byte[8*1024];
    while ((len = bis.read(bytes)) != -1) {
    	bos.write(bytes, 0 , len);
    }
    
    // 记录结束时间
    long end = System.currentTimeMillis();
    System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
}
缓冲流使用数组复制时间:666 毫秒
ew BufferedOutputStream(new           FileOutputStream("copy.exe"));
    
    // 读写数据
    int len = 0;
    byte[] bytes = new byte[8*1024];
    while ((len = bis.read(bytes)) != -1) {
    	bos.write(bytes, 0 , len);
    }
    
    // 记录结束时间
    long end = System.currentTimeMillis();
    System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
}
缓冲流使用数组复制时间:666 毫秒

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/codebull/p/13795454.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!