目录
一、文件
1、文件的定义
2、File类
🍅File类中的常见属性
🍅File类中的构造方法
🍅File类中的常用方法
二、文件内容的读取-数据流
🍅InputStream概述
🍅FileInputStream
🍅OutputStream 概述
🍅FileReader
🍅FileWriter
🍅Scanner
🍅PrintWriter
🌹综合案例1
🌹综合案例2
一、文件
1、文件的定义
需要知道一些简单的概念:
1、狭义上的文件
硬盘上保存的数据,都是“文件”来组织的,本质上都是二进制或者字符组织的数据,被打包成一个文件存储在硬盘中。常见的文件有图片(png),文本(txt),可执行文件(exe),音频和视频等(mp3)。其中的文件夹也是一种特殊的文件,也叫作目录。
通常说的文件都是存储在硬盘上的(实现数据的持久化),原因主要在于硬盘的特点:
(1)硬盘容量大,内存容量小;
(2)硬盘读写速度慢,内存读写速度快;
(3)硬盘造价低,内存成本高;
(4)硬盘上的数据就算断电也不会丢失,内存中的数据断电会丢失。
其中:1byte(1b) = 8bit;
1kb = 1024b;
1mb = 1024kb;
1gb = 1024mb;
2、广义上的文件
操作系统的主要功能是对计算机资源进行统一管理与分配。对于Linux系统来讲,所有的计算设备都会被描述(抽象为)文件。
3、访问目录
windows中的目录是默认是反斜杠\,但是用/斜杠也支持;在其他的系统中基本都是默认斜杠/。
2、File类
操作系统的一个重要功能就是对文件的管理,每个操作系统都有自己的一套API调用,Java作为一个跨平台的语言,JVM针对不同的操作系统做了一层封装,因此我们只需要使用JDK提供的关于文件操作的API就可以完成不同系统上的文件操作。
其中,输入和输出以内存为参照物的,输入指的是从外部输入到内存中,输出指的是将内存的数据输出到外部,比如磁盘,网卡等。
🍅File类中的常见属性
修饰符及类型 | 属性 | 说明 |
static String | pathSeparator | 依赖于系统的路径分隔符,String类型的表示 |
static char | pathSeparator | 依赖于系统的路径分隔符,char类型的表示 |
🍅File类中的构造方法
🍅File类中的常用方法
(1)获取路径的方法
修饰符及返回值类型 | 方法 | 说明 |
String | getParent() | 返回File对象的父目录文件路径 |
String | getName() | 返回File对象的纯文件名称 |
String | getPath() | 返回File对象的文件路径 |
String | getAbsolutePath() | 返回File对象的绝对路径 |
String | getCanonicalPath() | 返回File对象修饰过的绝对路径 |
(2)判断方法
修饰符及返回值类型 | 方法 | 说明 |
boolean | exists() | 判断File对象描述的文件是否真实存在 |
boolean | isDirectory() | 判断File对象代表的文件是不是一个目录 |
boolead | isFile() | 判断File对象代表的文件是否是一个普通文件 |
(3)创建文件
修饰符及返回值类型 | 方法 | 说明 |
boolean | creatNewFile() | 根据File对象,自动创建一个空文件。创建成功则返回True |
boolean | mkdir() | 创建File对象代表的目录 |
boolean | mkdirs() | 创建File对象代表的目录,如果必要,会创建中间目录 |
(4)显示文件
修饰符及返回值类型 | 方法 | 说明 |
String[] | list() | 返回File对象代表的目录下面的所有文件名 |
File[] | listFiles() | 返回File对象代表的目录下的所有文件,以File文件表示 |
(5)删除文件
修饰符及返回值类型 | 方法 | 说明 |
boolean | delete() | 根据File对象,删除该文件。成功后返回True |
boolean | deleteOnExit() | 根据File对象,标注文件将被删除,删除动作等到JVM运行结束后才进行 |
(6)判断文件是否可读写
修饰符及返回值类型 | 方法 | 说明 |
boolean | canRead() | 判断用户是否对文件有可读权限 |
boolean | canWrite() | 判断用户是否对文件有可写权限 |
boolean | renameTo(File dest) | 进行文件改名,也可以视为我们平时说的剪切,粘贴操作 |
二、文件内容的读取-数据流
🍅需要知道
输入流用于读取,输出流用于写入。
🍅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() | 关闭字节流 |
🍅1、FileInputStream
(构造方法)签名 | 说明 |
FileInputStream(File file) | 利用File构建文件输入流 |
FileInputStream(String name) | 利用文件路径构建文件输入流 |
将文件完全读完的两种方式。后一种的IO次数更少,性能更好。
🍅OutputStream 概述
修饰符及返回值类型 | 方法签名 | 说明 |
void | write(int b) | 写入字节数据(传入的值,最终都会被写入文件中) |
void | write(byte[] b) | 将b这个字符数组中的数据全部写入os中(传入的值,最终都会被写入文件中) |
void | write(byte[] b,int off,int len) | 将b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len个 |
void | close() | 关闭字节流 |
void | flush() | 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。 |
🍅FileReader
🍅FileWriter
注意:无论是输入流还是输出流,用完之后一定要close()。在写入内容之后,强烈建议用输出流的flush来刷新缓冲区。
🍅Scanner
🍅PrintWriter
🌹综合案例1
public class Exe01 {/*** 要求:扫描指定目录,找到目录中包含的所有指定字符的文件(不包含目录),并且后期询问用户是否要删除该文件* @param args*/public static void main(String[] args) throws IOException {//1、接收用户输入的扫描路径System.out.println("请输入要扫描的路径(绝对路径):");Scanner sc = new Scanner(System.in);String rootPath = sc.next();//2、路径的合法性校验File root = new File(rootPath);//2.1判断路径是否存在if(!root.exists()){System.out.println("路径不存在");//直接结束该方法return;}//2.2判断File是不是一个目录,如果不是目录则不合法if (!root.isDirectory()) {System.out.println("该指定的路径不是一个有效目录");return;}//3、接收要在目录中查找的文件名:我们把它叫做关键字System.out.println("请输入关键字:");String key = sc.next();if(key == null || key.equals("")){System.out.println("关键字不能为空");return;}//4、开始查找 该目录下的所有问津scan(root,key);}/*** 输入路径和文件,找到该路径下的所有文件名为key的文件* @param root 目录的路径* @param key 要在目录中查找的文件*/private static void scan(File root, String key) throws IOException {//1、先获取root下的所有文件,包括目录File[] files = root.listFiles();//2、递归的终止条件if(files == null || files.length == 0){return;}//3、开始遍历文件数组中的每个文件for (int i = 0; i < files.length; i++) {//3.1先取出每个文件File tempFile = files[i];//3.2判断是文件还是目录//如果是文件,判断是不是我们要找的文件(根据关键字判断)if(tempFile.isFile()){//获取文件的名字String fileName = tempFile.getName();if(fileName.contains(key)){System.out.println("找到文件"+tempFile.getCanonicalPath()+"是否需要删除(Y/N)");}//获取用户的选择Scanner sc = new Scanner(System.in);String choice = sc.next();//判断是否要删除if(choice.equalsIgnoreCase("y")){//删除文件tempFile.delete();System.out.println(tempFile.getCanonicalPath()+"删除成功");}}//说明是目录:则继续递归寻找文件else{scan(tempFile,key);}}}
}
🌹综合案例2
public static void main(String[] args) {//1、接收用户输入的源文件路径->要复制的文件System.out.println("请输入源文件路径(绝对路径):");Scanner sc = new Scanner(System.in);String sourcePath = sc.next();//2、路径的合法性校验File sourceFile = new File(sourcePath);//2.1判断路径是否存在if (!sourceFile.exists()) {System.out.println("源文件不存在");return;}//2.2判断是不是一个文件if (!sourceFile.isFile()) {System.out.println("源文件不是一个有效的文件");return;}//3、接收用户输入:要将复制后的文件放在哪个路径下System.out.println("请输入目标文件路径(绝对路径):");String destPath = sc.next();File destFile = new File(destPath);//3.1目标文件的合法性校验if(destFile.exists()){System.out.println("目标文件已存在");return;}//3.2判断目标文件的父目录是否存在if (!destFile.getParentFile().exists()) {System.out.println("目标文件的父目录不存在");return;}//4、循环读取源文件的内容并写入到目标文件中try(FileInputStream inputStream = new FileInputStream(sourceFile);FileOutputStream outputStream = new FileOutputStream(sourceFile)) {//4.1定义一个byte数组用来作为输出型参数,保存每次读取到的文件内容byte[] bytes = new byte[1024];//4.2开始循环读取内容while (true){int len = inputStream.read(bytes);//4.3已经读完了if(len == -1){break;}//4.4 开始写入到目标文件中outputStream.write(bytes);//4.5 强制刷新缓冲区outputStream.flush();}System.out.println("复制成功");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e){e.printStackTrace();}}
注意:
努力学习,等待下一个火锅日~~