File类和InputStream, OutputStream的用法

文章目录

一.File概述

属性

修饰符及类型 属性 说明
static String pathSeparator 依赖于系统的路径分隔符,String 类型的表示
static char pathSeparator 依赖于系统的路径分隔符,char 类型的表示

构造方法

签名 说明
File(File parent, String child) 根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname) 根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者 相对路径
File(String parent, String child) 根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用 路径表示

方法

修饰符及返回类型 方法签名 说明
String getParent() 返回 File 对象的父目录文件路径
String getName() 返回 FIle 对象的纯文件名称
String getPath() 返回 File 对象的文件路径
String getAbsolutePath() 返回 File 对象的绝对路径
String getCanonicalPath() 返回 File 对象的修饰过的绝对路径
boolean exists() 判断 File 对象描述的文件是否真实存在
boolean isDirectory() 判断 File 对象代表的文件是否是一个目录
boolean isFile() 判断 File 对象代表的文件是否是一个普通文件
boolean createNewFile() 根据 File 对象,自动创建一个空文件。成功创建后返 回 true
boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit() 根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行
String[] list() 返回 File 对象代表的目录下的所有文件名
File[] listFiles() 返回 File 对象代表的目录下的所有文件,以 File 对象表示
boolean mkdir() 创建 File 对象代表的目录
boolean mkdirs() 创建 File 对象代表的目录,如果必要,会创建中间目录
boolean renameTo(File dest) 进行文件改名,也可以视为我们平时的剪切、粘贴操作
boolean canRead() 判断用户是否对文件有可读权限
boolean canWrite() 判断用户是否对文件有可写权限

代码示例

get()系列

java 复制代码
import java.io.File;
import java.io.IOException;
 public class Main {
 	public static void main(String[] args) throws IOException {
 		File file = new File("..\\hello-world.txt");    
        System.out.println(file.getParent());
		System.out.println(file.getName());
		System.out.println(file.getPath());
		System.out.println(file.getAbsolutePath());
 		System.out.println(file.getCanonicalPath());
    }
 }
 

运行结果

java 复制代码
 ..
 hello-world.txt
 ..\hello-world.txt
 D:\代码练习\文件示例1\..\hello-world.txt
 D:\代码练习\hello-world.txt

二.文件内容的读写 ---- 数据流

InputStream 概述

方法

修饰符及返回值类型 方法签名 说明
int read() 读取一个字节的数据,返回 -1 代表已经完全读完了
int read(byte[] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了
int read(byte[] b, int off, int len) 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返 回实际读到的数量;-1 代表以及读完了
void close() 关闭字节流

说明

InputStream只是一个抽象类, 要使用还需具体的实现类. 关于InputStream的实现类有很多, 基本可以认为不同的输入设备都可以对应一个InputStream类, 我们现在只关心文件的读取, 所以使用FileInputStream

FileInputStream 概述

构造方法

签名 说明
FileInputStream(File file) 利用 File 构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流

代码示例

注记 :

​ 以下的代码示例中的 try with resources 语法目的就是 ( ) 定义的变量, 会在 try{} 代码块结束的时候(正常结束还是抛出异常)

自动调用其中的 close() 方法, 但要求写到 ( ) 中的对象都必须实现 closeable 接口

流对象都可以这么写 ! ! !

将文件完全读完的两种方式。相比较而言,后一种的 IO 次数更少,性能更好。

示例1

java 复制代码
import java.io.*;

// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "Hello" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            while (true) {
                int b = is.read();
                if (b == -1) {
                    // 代表文件已经全部读完
                    break;
                }
                System.out.printf("%c", b);
            }
        }
    }
}

示例2

java 复制代码
import java.io.*;

// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "Hello" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            byte[] buf = new byte[1024];
            int len;
            while (true) {
                len = is.read(buf);
                if (len == -1) {
                    // 代表文件已经全部读完
                    break;
                }
                for (int i = 0; i < len; i++) {
                    System.out.printf("%c", buf[i]);
                }
            }
        }
    }
}

利用 Scanner 进行字符读取

上述例子中, 我们看到了对字符类型直接使用InputStream进行读取是很麻烦且困难的, 所以我们使用一种我们之前比较熟悉的类来完成工作, 就是Scanner类.

构造方法 说明
Scanner(InputStream is, String charset) 使用 charset 字符集进行 is 的扫描读取

代码示例

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            try (Scanner scanner = new Scanner(is, "UTF-8")) {
                while (scanner.hasNext()) {
                    String s = scanner.next();
                    System.out.print(s);
                }
            }
        }
    }
}

OutputStream概述

方法

修饰符及返回值类型 方法签名 说明
void write(int b) 写入一个字节的数据
void write(byte[] b) 将 b 这个字符数组中的数据全部写入 os 中
int write(byte[] b, int off, int len) 将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
void close() 关闭字节流
void flush() 刷新缓冲区的数据

重点: flush()

我们知道I/O的速度是很慢的, 所以大多数的OutputStream为了减少设备操作的次数, 在写数据的时候会先将数据暂时写入内存的一个指定区域内, 知道该区域满了或者达成其他指定条件时才真正将数据写入设备中, 这个区域一般称为缓冲区. 但会造成一个结果, 就是我们写的数据很可能会遗留一部分在缓冲区. 需要在最后或者合适的位置调用flush()(刷新), 将数据刷新到设备中.

说明

OutputStream同样只是一个抽象类, 要使用也需要具体的实现类. 我们现在只关心写入文件中, 所以使用FileOutputStream

利用 OutputStreamWriter 进行字符写入

代码示例

java 复制代码
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            os.write('H');
            os.write('e');
            os.write('l');
            os.write('l');
            os.write('o');
            // 不要忘记 flush
            os.flush();
        }
    }
}

利用 PrintWriter 进行打印

代码示例

PrintWriter 类中提供了我们熟悉的 print/println/printf 方法

java 复制代码
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
                try (PrintWriter writer = new PrintWriter(osWriter)) {
                    writer.println("我是第一行");
                    writer.print("我是第二行\r\n");
                    writer.printf("%d: 我是第三行\r\n", 1 + 1);
                    writer.flush();
                }
            }
        }
    }
}

三.小程序练习

要求: 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要

删除该文件

代码示例

java 复制代码
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要扫描的根目录(绝对路径 OR 相对路径): ");
        String rootDirPath = scanner.next();
        File rootDir = new File(rootDirPath);
        if (!rootDir.isDirectory()) {
            System.out.println("您输入的根目录不存在或者不是目录,退出");
            return;
        }
        System.out.print("请输入要找出的文件名中的字符: ");
        String token = scanner.next();
        List<File> result = new ArrayList<>();
        // 因为文件系统是树形结构,所以我们使用深度优先遍历(递归)完成遍历
        scanDir(rootDir, token, result);
        System.out.println("共找到了符合条件的文件 " + result.size() + " 个,它们分别是");
        for (File file : result) {
            System.out.println(file.getCanonicalPath() + " 请问您是否要删除该文件?y/n");
            String in = scanner.next();
            if (in.toLowerCase().equals("y")) {
                file.delete();
            }
        }
    }

    private static void scanDir(File rootDir, String token, List<File> result) {
        File[] files = rootDir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                scanDir(file, token, result);
            } else {
                if (file.getName().contains(token)) {
                    result.add(file.getAbsoluteFile());
                }
            }
        }
    }
}
相关推荐
程序媛小果5 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
追风林10 分钟前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
芒果披萨24 分钟前
El表达式和JSTL
java·el
duration~1 小时前
Maven随笔
java·maven
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java
blammmp2 小时前
Java:数据结构-枚举
java·开发语言·数据结构
暗黑起源喵2 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong2 小时前
Java反射
java·开发语言·反射
九圣残炎3 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode