java之file和IO流

目录

File

​编辑

IO流

字节流

FileOutputStream:向本地磁盘输出文件

FileInputStream读取本地文件​编辑

拷贝文件

字符集

字符流

如何区分什么时候使用字节流,什么时候使字符流呢?

缓冲流

转换流

序列化流

字节打印流

字符转换流

[Hutool FileUtil 常用方法讲解](#Hutool FileUtil 常用方法讲解)

导入依赖

[Maven 依赖](#Maven 依赖)

常用方法

[1. file 方法](#1. file 方法)

[2. touch 方法](#2. touch 方法)

方法讲解

[4. appendLines 方法](#4. appendLines 方法)

[5. readLines 方法](#5. readLines 方法)

[6. readUtf8Lines 方法](#6. readUtf8Lines 方法)

[7. copy 方法](#7. copy 方法)


File

java 复制代码
package file;

import java.io.File;

public class demo1 {
    public static void main(String[] args) {
        File file = new File("D:\\javacode\\My_Thread");
        System.out.println(file.isFile()); // 是否是一个文件
        System.out.println(file.isDirectory()); // 是否是一个文件夹
        System.out.println(file.exists()); // 是否存在

        // file.length() 返回文件的大小(字节数)
        // 这个方法只能获取文件的大小,单位是字节,如果单位我们要是M,6,可以不断的除以1024
        // 这个方法无法获取文件夹的大小
        File file1 = new File("D:\\DataGrip 2024.1.3\\build.txt");
        System.out.println(file1.length());

        // file.getAbsoluteFile()获取绝对路径
        System.out.println("========================");
        System.out.println(file1.getAbsoluteFile());

        System.out.println("=========================");
        // file.getPath() 返回定义文件时使用的路径 括号内的参数是什么返回的就是什么
        System.out.println(file.getPath());

        System.out.println("=========================");
        // file.getName() 获取名字
        // 如果是文件, 会返回文件名+后缀名
        // 如果是文件夹 会返回文件夹的名字
        System.out.println(file1.getName());
        System.out.println(file.getName());
    }
}
  1. createNewFile 创建一个新的空的文件夹

如果当前路径表示的文件是不存在的,则创建成功,方法返回true,如果当前路径表示的文件是存在的,则创建失败,方法返回false。

如果父级路径是不存在的,那么方法会有异常IOException

createNewFile 方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件

  1. mkdir 创建一个单级文件夹

windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false

mkdir方法只能创建单级文件夹,无法创建多级文件夹

  1. mkdirs 创建多级文件夹

既可以创建单级的,又可以创建多级的文件夹

  1. delete 删除空的文件

如果删除的是文件,则直接删除,不走回收站。如果删除的是空文件夹,则直接删除,不走回收站如果删除的是有内容的文件夹,则删除失败

IO流

字节流

FileOutputStream:向本地磁盘输出文件

java 复制代码
package IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("test.txt",true);
        // 第二个参数表示续写,也就是不会清空原来文件里面的数据
        byte []b = {97,98,99,100};
//        fileOutputStream.write(b);
        // 参数一: 数组
        //参数二: 起始索引
        //参数三: 个数
        fileOutputStream.write(b,1,2); // 98 99-> b c

        String n = "\r\n"; // 换行
        byte[] bytes = n.getBytes();
        fileOutputStream.write(bytes);

        String s = "你真可爱!!!";
        byte[] bytes1 = s.getBytes();
        fileOutputStream.write(bytes1);
        fileOutputStream.close();
    }
}

FileInputStream读取本地文件

拷贝文件

java 复制代码
package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\桌面\\新建文本文档.txt");
        FileOutputStream fos = new FileOutputStream("src\\IO\\copy.txt");

         byte[] bytes=  new byte[2]; // 一般数组长度可以定义为1024*1024*5 -> 5 MB
         int len;
         while((len =  fis.read(bytes)) != -1){
             fos.write(bytes,0,len); // 读多少,写多少
         }
         // 先打卡的后关闭
         fos.close();
         fis.close();
    }
}

字符集

UTF-8不是一种字符集是Unicode的一种编码方式

字符流

如何区分什么时候使用字节流,什么时候使字符流呢?

只需要记住一点,那就是如果是拷贝文件的时候就使用字节流。

如果是读写文件就是字符流

拷贝文件夹的时候存在子文件 ,代码示例:

使用字节流

java 复制代码
package IO;

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

public class practice {
    public static void main(String[] args) throws IOException {
//        拷贝一个文件夹考虑子文件夹
        File src = new File("D:\\桌面\\奖状");
        File dest = new File("D:\\奖状copy");
        copydir(src,dest);
    }

    private static void copydir(File src, File dest) throws IOException {
        // 创建文件夹
        dest.mkdirs();
        File[] files = src.listFiles();
        for (File file : files) {
            if(file.isDirectory()){
                // 说明是一个文件夹 递归
                // 需要递归调用时在 dest 的基础上拼接当前子文件夹名,生成目标文件夹路径,从而保持源文件夹的层级结构
                copydir(file,new File(dest,file.getName()));
            }else{
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(dest,file.getName()));
                // 这里不能仅仅用dest,因为 dest 是当前级文件夹路径,需要为每个文件或子文件夹指定完整路径。
                /*
                需要在 dest 的基础上拼接文件名,生成完整的目标文件路径
                假设 src 是 D:\桌面\奖状\file1.txt。
                //dest 是 D:\奖状copy。
                如果直接用 dest,那么程序会尝试将文件直接写入到 D:\奖状copy,但此路径是一个文件夹路径,不是文件路径,会导致错误。
                */
                byte[] b = new byte[5*1024*1024];
                int len;
                while((len = fis.read(b)) != -1){
                    fos.write(b,0,len);
                }
                fos.close();
                fis.close();
            }
        }
    }
}

无论使用 FileReader 还是 FileInputStream,读到的都是字节数据 ,而不是直接的字符内容,如果直接存储这些 int 值,你看到的可能是数字而不是字符本身。因此,强转为 char 是必要的。 如果使用字节流和 byte[] 缓存,可以直接读写文件,不需要字符的强转

缓冲流

java 复制代码
package IO.Buffer;

import java.io.*;

public class demo1 {
    public static void main(String[] args) throws IOException {
        // 创建字节缓冲流拷贝文件

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src\\IO\\test.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("src\\IO\\Buffer\\copy.txt"));

        // 循环拷贝 一次一个字节
        int len;
        while((len = bis.read()) != -1){
            bos.write(len);
        }
        // 一次多读写几个字节
        byte [] b = new byte[1024];
        while ((len = bis.read(b)) != -1){
            bos.write(b,0,len);
        }
        // 释放资源
        bos.close();
        bis.close();
    }
}
java 复制代码
package IO.Buffer;

import java.io.*;
// 使用缓冲字符流来一行一行拷贝
public class demo2 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("src\\IO\\test.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("src\\IO\\Buffer\\copyChar.txt"));
        String read;
        while((read = br.readLine()) != null){
            bw.write(read);
            bw.newLine();
        }
        bw.close();
        br.close();
    }
}

注意,在写入本地文件的时候。当本地文件存在该文件 就会清空该文件内容。所以使用IO流我们有一个原则就是随用随New随关。

转换流

  1. 指定字符集读写(JDK11之后淘汰了)

  2. 字符流想要使用字符流里面的方法

代码示例:

利用转换流按照指定的字符编码读取

java 复制代码
package IO.Bridge;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;

public class demo1 {
    public static void main(String[] args) throws IOException {
        // 利用转换流按照指定字符编码读取
        // JDK11之前需要创建InputStreamReader和OutPutStreamWriter
        
        // JDK11之后的替代方案:直接创建FileReader对象
        FileReader fr = new FileReader("D:\\桌面\\新建文本文档.txt", Charset.forName("GBK"));
        FileWriter fw = new FileWriter("src\\IO\\Bridge\\boy.txt",Charset.forName("GBK"));
        int len;
        while((len = fr.read()) != -1){
            fw.write((char) len);
        }
        fw.close();
        fr.close();
    }
}
java 复制代码
package IO.Bridge;

import java.io.*;
public class demo2 {
    public static void main(String[] args) throws IOException {
        // 利用字节流读取文件的数据,每次读取一整行,而且不能出现乱码
        // 字节流读取数据会出现乱码 所以我们需要利用字符流
        // 字节流不能一整行读 所以我们需要结合字符缓冲流
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("src\\IO\\Bridge\\boy.txt")));
        String line;
        while((line = br.readLine())!= null){
            System.out.println(line);
        }
    }
}

序列化流

序列化流

java 复制代码
package IO.Serialization;


import java.io.*;

public class demo1 {
    public static void main(String[] args) throws IOException {
        Student student = new Student("南京", "张三",24);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\IO\\Serialization\\serialization.txt"));
        oos.writeObject(student);
        oos.close();
    }
}
/*
 需要实现Serializable这个接口 没有抽象方法,标记型接口
 r一旦实现类这个接口,那么就表示当前的Student类可以被序列化
*/
class Student implements Serializable {
    @Serial
    private static final long serialVersionUID = -518532692387043786L; // 定义一个UID版本号

    // transient :瞬态关键字
    private transient String addr;

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

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

    private String name;
    private int 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;
    }

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

    public Student() {
    }
}

反序列化流

java 复制代码
package IO.Serialization;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class demo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\IO\\Serialization\\serialization.txt"));
        Student o = (Student) ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

字节打印流

字符转换流

字符打印流和字节打印流的方法是一样的

Hutool FileUtil 常用方法讲解

FileUtil 是 Hutool 中一个强大的文件操作工具类,提供了文件读写、创建、删除、拷贝等常用操作。

导入依赖

在项目中使用 Hutool 之前,需要添加依赖。

Maven 依赖

XML 复制代码
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.20</version>
</dependency>

常用方法

1. file 方法

功能 : 根据参数创建一个 File 对象。

使用场景 : 用于获取一个 File 对象,而不需要关心文件或目录是否存在。

java 复制代码
File file = FileUtil.file("example.txt");
System.out.println(file.getAbsolutePath());

2. touch 方法

功能: 根据参数创建一个文件。

特点:

如果文件已存在,则返回已存在的文件。

如果文件不存在,则会创建新的文件。

使用场景: 用于快速创建文件。

java 复制代码
File file = FileUtil.touch("newFile.txt");
System.out.println("文件是否存在: " + file.exists());

方法讲解

以下是您提供图片中涉及到的 Hutool FileUtil 方法的详细说明和用法:

功能: 将集合中的数据写入到文件中,采用覆盖模式。

参数说明:

数据集合 (Collection<?> 类型)。

文件路径或 File 对象。

字符集编码。

使用场景: 用于将一组数据快速写入到文件中,覆盖旧内容。

示例代码:

java 复制代码
List<String> lines = Arrays.asList("第一行", "第二行", "第三行");
FileUtil.writeLines(lines, "example.txt", Charset.forName("UTF-8"));

4. appendLines 方法

功能: 将集合中的数据追加到文件中,不覆盖原有内容。

参数说明 : 与 writeLines 相同。

使用场景: 用于在已有文件内容后追加新数据。

java 复制代码
List<String> lines = Arrays.asList("追加内容1", "追加内容2");
FileUtil.appendLines(lines, "example.txt", Charset.forName("UTF-8"));

5. readLines 方法

功能: 按指定字符集编码读取文件内容,并将每一行作为集合的一个元素。

参数说明:

文件路径或 File 对象。

字符集编码。

使用场景: 用于逐行读取文件内容。

示例代码:

java 复制代码
List<String> lines = FileUtil.readLines("example.txt", Charset.forName("UTF-8"));
lines.forEach(System.out::println);

6. readUtf8Lines 方法

功能: 按 UTF-8 编码格式读取文件内容,返回集合。

特点: 专门针对 UTF-8 编码文件的快捷读取。

使用场景: 用于读取 UTF-8 格式的文件内容。

java 复制代码
List<String> lines = FileUtil.readUtf8Lines("example.txt");
lines.forEach(System.out::println);

7. copy 方法

功能: 拷贝文件或目录。

参数说明:

源文件路径或 File 对象。

目标文件路径或 File 对象。

是否覆盖目标文件(boolean 类型)。

使用场景: 用于文件或目录的复制。

java 复制代码
FileUtil.copy("source.txt", "destination.txt", true);
FileUtil.copy("sourceDir", "destinationDir", true);

FileUtil 简化了许多常见的文件操作,推荐在 Java 项目中广泛使用!

相关推荐
纪元A梦8 分钟前
贪心算法应用:边着色问题详解
java·算法·贪心算法
王燕龙(大卫)38 分钟前
递归下降算法
开发语言·c++·算法
工业互联网专业1 小时前
基于springboot+vue的社区药房系统
java·vue.js·spring boot·毕业设计·源码·课程设计·社区药房系统
API小爬虫1 小时前
如何用爬虫获得按关键字搜索淘宝商品
java·爬虫·python
青出于兰1 小时前
C语言|函数的递归调用
c语言·开发语言
2401_858286112 小时前
CD36.【C++ Dev】STL库的string的使用 (下)
开发语言·c++·类和对象·string
sanx182 小时前
从零搭建体育比分网站完整步骤
java·开发语言
夏季疯2 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.29)
java·笔记·学习
若水晴空初如梦2 小时前
QT聊天项目DAY09
开发语言·qt·bootstrap
努力也学不会java2 小时前
【HTTP】《HTTP 全原理解析:从请求到响应的奇妙之旅》
java·网络·网络协议·http