Java的File类和IO流

Java的File类和IO流

File类

一、File类的理解

  • File类位于java.io包下
  • File类的一个对象,对应与操作系统下的一个文件或一个文件目录(或文件夹)

二 、内部API使用说明

2.1 构造器

  1. public File(String pathname):以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储
  2. publicFile(String parent,String child):以parent为父路径,child为子路径创建File对象
  3. publicFile(File parent,String child):根据一个父File对象和子文件路径创建File对象

文件路径的表达方式

  • 方式1:绝对路径——以windows操作系统为例,包括盘符在内的文件或文件目录的完整路径
  • 方式2:相对路径——相对于某一个文件目录来讲的相对的位置
    • 在Idea中如果使用单元测试方法:相对于当前的module来讲
    • 在Idea中如果使用main()方法:相对于当前的project来讲(在系统属性user.dir中创建)
import java.io.File;

public class FileTest {
    public static void main(String[] args) {
        // 创建FIle对象 方式一
        // 绝对路径
        File file1 = new File("d/io/hello.txt");
        System.out.println(file1.getAbsolutePath());    // 输出: D:\idea_workspace\my_jinjie\d\io\hello.txt

        // 相对路径
        File file2 = new File("ab");
        System.out.println(file2.getAbsoluteFile());    // 输出: D:\idea_workspace\my_jinjie\ab

        // 方式二
        // 参数1:一定是一个文件目录
        // 参数2:可以是一个文件,也可以是一个文件目录
        File file3 = new File("d:\\","abc.txt");
        File file4 = new File("abc", "a12");
        System.out.println(file4.getAbsoluteFile());    // 输出: D:\idea_workspace\my_jinjie\abc\a12

        // 方式三
        // 参数1:是一个File文件目录
        // 参数2:可以是一个文件,也可以是一个文件目录
        File file5 = new File(file4, "ab.txt");
        System.out.println(file5.getAbsoluteFile());    // 输出: D:\idea_workspace\my_jinjie\abc\a12\ab.txt
    }
}

2.2 方法

a、获取文件和目录的基本信息
  • public String getName():获取名称
  • public String getPath():获取路径
  • public String getAbsolutePath():获取绝对路径
  • public File getAbsoluteFile():获取绝对路径表示的文件
  • public String getParent():获取上层文件目录路径。若无,返回null
  • public long length():获取文件长度(即:字节数)。不能获取目录的长度
  • public long lastModified():获取最后一次的修改时间,毫秒值
import java.io.File;
import java.util.Date;

public class FileTest1 {
    public static void main(String[] args) {
        // 文件的方法
        File file1 = new File("Hello.txt");
        System.out.println(file1.getName());
        System.out.println(file1.getPath());
        System.out.println(file1.getAbsolutePath());
        // 返回值为一个绝对路径的File文件
        System.out.println(file1.getAbsoluteFile());
        System.out.println(file1.getAbsoluteFile().getParent());
        System.out.println(file1.getParent());
        System.out.println(file1.length());
        System.out.println(file1.lastModified());
        // 打印Date类型显示
        Date d = new Date(file1.lastModified());
        System.out.println(d);

        System.out.println("--------------------------");
        // 使用绝对路径
        File file2 = new File("D:\\io\\io1");
        System.out.println(file2.getName());
        System.out.println(file2.getPath());
        System.out.println(file2.getAbsolutePath());
        System.out.println(file2.getAbsoluteFile());
        System.out.println(file2.getAbsoluteFile().getParent());
        System.out.println(file2.getParent());
        System.out.println(file2.length());
        System.out.println(file2.lastModified());

        System.out.println();
        System.out.println(System.getProperty("user.dir"));
    }
}

在这里插入图片描述

b、列出目录的下一级
  • public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录
  • public File[] listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录
c、文件的重命名
  • public boolean renameTo(File dest):把文件重命名为指定的文件路径
import java.io.File;

public class FileTest2 {
    public static void main(String[] args) {
        // 列出目录的下一层
        // 方式1:返回一个String数组
        File file = new File("D:\\java\\资料");
        String[] str = file.list();
        for (String s : str) {
            System.out.println(s);
        }

        System.out.println("--------------------");

        // 方式2:返回一个File数组
        File[] files = file.listFiles();
        for (File f : files) {
            System.out.println(f.getName());
        }

        // 文件的重命名
        // 要求: file1必须存在,且file2必须不存在,且file2所在的文件目录需要存在
        File file1 = new File("Hello.txt");
        File file2 = new File("D:\\io\\abc.txt");

        boolean renameSuccess = file1.renameTo(file2);
        System.out.println(renameSuccess ? "重命名成功" : "重命名失败");

        // 给该目录下的文件全部加上前缀
        File file3 = new File("D:\\java\\资料\\拓展练习");
        File[] files3 = file3.listFiles();
        for (File fil : files3) {
            String newName = "G_" + fil.getName();
            File newFile = new File(fil.getParent(), newName);

            boolean success = fil.renameTo(newFile);
            System.out.println(success ? "重命名成功" : "重命名失败");
        }
    }
}
d、判断功能的方法
  • public boolean exists():此File表示的文件或目录是否实际存在
  • public boolean isDirectory():此File表示的是否为目录
  • public boolean isFile():此File表示的是否为文件
  • public boolean canRead():判断是否可读
  • public boolean canWrite():判断是否可写
  • public boolean isHidden():判断是否隐藏
e、创建和删除功能
  • public boolean createNewFile():创建文件。若文件存在,则不创建,返回false
  • public boolean mkdir():创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建
  • public boolean mkdirs():创建文件目录。如果上层文件目录不存在,一并创建。
  • public boolean delete():删除文件或者文件夹

删除注意事项

  1. Java中的删除不走回收站
  2. 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
import java.io.File;
import java.io.IOException;

public class FileTest3 {
    public static void main(String[] args) throws IOException {
        // 判断功能的方法
        File file1 = new File("D:\\io\\abc.txt");
        System.out.println(file1.exists());
        System.out.println(file1.isDirectory());
        System.out.println(file1.isFile());
        System.out.println(file1.canRead());
        System.out.println(file1.canWrite());
        System.out.println(file1.isHidden());

        // 创建和删除功能
        File file2 = new File("D:\\io\\hello.txt");

        if (!file2.exists()) {
            boolean success = file2.createNewFile();
            System.out.println(success ? "创建成功" : "创建失败");
        }

        // 删除文件
        boolean successful = file2.delete();
        System.out.println(successful ? "删除成功" : "删除失败");
    }
}

File类中声明了新建、删除、获取名称、重命名等方法,并没有涉及文件内容的读写操作。要想实现文件内容的读写,我们就需要使用io流

File类的对象,通常是作为io流操作的文件的端点出现的

  • 代码层面,将File类的对象作为参数传递到IO流相关类的构造器中
拓展:

文件过滤器FilenameFilter 是 Java 中用于过滤目录中的文件名的**接口**。它通常与 File 类的 listlistFiles 方法一起使用,允许我们根据自定义规则筛选出符合条件的文件或目录。

FilenameFilter 的核心方法

FilenameFilter 是一个函数式接口,只有一个抽象方法:

boolean accept(File dir, String name);

方法参数

  • File dir:当前文件所在的目录。
  • String name:当前文件的名称(不包括路径)。

返回值

  • 返回 true:表示接受这个文件或目录。
  • 返回 false:表示过滤掉这个文件或目录。

示例

  • 需求:判断指定目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称
import java.io.File;
import java.io.FilenameFilter;

public class Demo02 {
    public static void main(String[] args) {
        File dir = new File("D:\\java\\素材\\image\\animal\\animal1");

        // 方式一:
        String[] listFiles = dir.list();
        for (String s : listFiles) {
            if(s.endsWith(".jpg")) {
                System.out.println(s);
            }
        }

        // 方式二:使用文件过滤器
        String[] listFiles1 = dir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".jpg");
            }
        });
        for (String s : listFiles1) {
            System.out.println(s);
        }
    }
}

IO流

一、IO流的分类

  • 按数据流向不同分为:

    • 输入流:把数据从其他设备上读取到内存中的流
    • 输出流:把数据从内存 中写出到其他设备上的流
  • 按操作数据单位的不同分为:

    • 字节流:以字节为单位,读写数据的流(例如图片、音视频等
    • 字符流:以字符为单位,读写数据的流(例如.txt后缀的文件,里面由字符组成
  • 按IO流的角色不同分为:

    • 节点流:直接从数据源或目的地读写数据(能够直接来操作文件
    • 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

二、基础IO流的框架

抽象基类输入流输出流
字节流InputStreamOutputStream
字符流ReaderWriter
抽象基类4个节点流(也称为文件流)
InputStreamFileInputStream
OutputStreamFileOutputStream
ReaderFileReader
WriterFileWriter

三、FileReaderFileWriter的使用

3.1 执行步骤

  1. 创建读取或写出的File类的对象
  2. 创建输入流和输出流
  3. 具体的读入或写出的过程
    • 读入:read(char[] cbuffer)
    • 写出:write(String str)/write(char[] cbuffer, 0, len)
  4. 关闭流资源,避免内存的泄漏

3.2 注意事项

  • 因为涉及到流资源的关闭操作,所以出现异常的话,需要使用try-catch-finally的方式来处理异常
  • 对于输入流来讲,要求File类的对象对应的物理磁盘上的文件必须存在;否则,会报FileNotFoundException
  • 对于输出流来讲,File类的对象对应的物理磁盘上的文件可以不存在
    • 如果此文件不存在,则在输出的过程中,会自动创建此文件,并写出数据到此文件中
    • 如果此文件存在:
      • 使用FileWriter(Filefile)或FileWriter(File file, false):输出数据过程中,会新建同名的文件对现有的文件进行覆盖
      • 使用FileWriter(Filefile, true):过程中,会在现有的文件的末尾追加写出内容

读取示例

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderWriterTest03 {
    public static void main(String[] args) {
        // 对读入进行优化,每次读取多个字符存放到字符数组中,减少了与磁盘交互的次数,提升效率
        FileReader fr = null;

        try {
            // 1. 创建File类的对象,对应着hello.txt文件
            File file = new File("hello.txt");

            // 2. 创建输入型的字符流,应用于读取数据
            fr = new FileReader(file);

            char[] cbuffer = new char[5];

            // 3. 读取数据,并显示在控制台上
            int len;
            while ((len = fr.read(cbuffer)) != -1) {
                for (int i = 0; i < len; i++) {
                    System.out.print(cbuffer[i]);
                }
            }
        } catch (
                IOException e) {
            System.out.println(e.getMessage());
        } finally {
            // 4. 流资源的关闭操作(必须要关闭,否则会内存泄漏)
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());;
            }
        }
    }

}
  • 使用.read(cbuffer)时,返回值是该次读取的字符的个数,且会将该次读取的字符放入这个数组中

每次读取文件时,与磁盘交互次数多会导致速率变慢,因为磁盘I/O的速度远慢于内存访问的速度,频繁与磁盘交互会带来显著的性能开销

写出示例

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileReaderWriterTest04 {
    public static void main(String[] args){
        // 将内存中的数据写出到指定的文件中
        FileWriter fw = null;

        try {
            // 1. 创建File类对象,指明要写出的文件名称
            File file = new File("info.txt");

            // 2. 创建输出流
            fw = new FileWriter(file);
            // 默认是文件覆盖的形式
//            fw = new FileWriter(file, false);
            // 改成true,则会在现有文件的基础上往后追加
//            fw = new FileWriter(file, true);

            // 3. 写出的具体过程
            fw.write("I love java\n");
            fw.write("java love me\n");
            fw.write("great");
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

3.3 结合练习

  • 需求:复制一份hello.txt文件,命名为hello_copy.txt的文件
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileReaderWriterTest05 {
    public static void main(String[] args){
        // 复制一份hello.txt文件,命名为hello_copy.txt
        FileReader fr = null;
        FileWriter fw = null;

        try {
            // 1. 创建File类的对象
            File src = new File("hello.txt");
            File src2 = new File("hello_copy.txt");

            // 2. 创建输入流和输出流
            fr = new FileReader(src);
            fw = new FileWriter(src2);

            int len;    // 记录每次读入到arr中字符的个数
            char[] arr = new char[5];
            while ((len = fr.read(arr)) != -1) {
//                for (int i = 0; i < len; i++) {
//                    fw.write(arr[i]);
//                }
                fw.write(arr, 0, len);
                // 上述方法形参 (数组名,起始索引,结束索引)
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

四、FileInputStreamFileOutputStream的使用

4.1 执行步骤

  1. 创建读取或写出的File类的对象
  2. 创建输入流或输出流
  3. 具体的读入或写出的过程
    • 读入:read(byte[] buffer)
    • 写出:write(byte[] buffer,0,len)
  4. 关闭流资源,避免内存泄漏

4.2 注意事项

  • 对于字符流,只能用来操作文本文件,不能用来处理非文本文件的
  • 对于字节流,通常是用来处理非文本文件的。但是,如果涉及到文本文件的复制操作,也可以使用字节流
  • 说明:
    • 文本文件:.txt、.java、.c、.cpp、.py
    • 非文本文件:.doc、.xls、.jpg、.pdf、.mp3、.mp4

4.3 综合练习

  • 需求:复制一份dog.txt文件,命名为dog_copy.txt
import java.io.*;

public class FileStreamTest01 {
    public static void main(String[] args) {
        // 需求:复制一份dog.jpg文件,命名为dog_copy.jpy
        FileInputStream fis = null;
        FileOutputStream fos = null;

        try {
            // 1. 创建相关的File类的对象
            File file1 = new File("dog.jpg");
            File file2 = new File("dog_copy.jpg");
            // 2. 创建相关的字节流
            fis = new FileInputStream(file1);
            fos = new FileOutputStream(file2);
            // 3. 数据的读入和写出
            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());;
        } finally {
            // 4. 关闭资源
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值