作者主页:paper jie_博客
本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。
本文于《JavaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将基础知识一网打尽,希望可以帮到读者们哦。
其他专栏:《MySQL》《C语言》《javaSE》《数据结构》等
内容分享:本期将会分享文件操作与IO的集合类芝士
目录
认识文件
文件的结构组织和目录
文件路径
二进制文件与文本文件
Java中操作文件
File概述
属性
构造方法
方法
文件的读写 - 数据流
InputStre
FileInputStream
OutputStream
FIleOutputStream
Scanner
小程序练习
扫描指定目录,找到指定文件
文件复制
扫描指定目录,通过文件内容来寻找指定文件
认识文件
针对硬盘这种持久化存储的IO存储设备,当我们想要进行数据保存的时候,往往不是一个整体,而是独立成一个一个的单位来存储.这个独立的单位被抽象成文件的概念.文件除了有数据内容外,还有一部分信息,比如:文件名,文件类型,文件大小等并不作为文件的数据而存在,这部分信息称为文件的元信息.
文件的结构组织和目录
随着文件数量的增加,文件的系统管理的需要日益迫切.而我们的操作系统的一个板块就有一个专门管理文件 - 文件系统. 有它将硬件细节封装起来,提供统一的API供我们使用.而此处的文件系统就是按照树型结构来组织文件的.这就是我们平时锁的文件夹或者目录的概念.
文件路径
如何在文件系统中定位到我们的一个唯一的文件就需要使用到我们的路径.路径我们可以从树的角度出发,树的每一个节点都可以被一条从根开始,一直到达叶子节点的路径锁描述.这就是一个文件的绝对路径.
除了可以从根结点开始描述路径我们也可以从任意结点出发,进行路径的描述,而这种描述方式就是相对路径.就是对于当前所在结点的一条路径.
这里:
. 代表当前路径
.. 代表当前路径上的前一个路径
二进制文件与文本文件
文件中,根据其保存的数据不同,也经常被分为不同的类型.我们一般分为文本文件和二进制文件,分别指保存字符集编码的文本和按照标准格式的非被字符集编码过的文件.
这里有一个简单区别他们的方式: 看的懂的文件就是文本文件,看不懂的文件就是二进制文件.
在Windows操作系统上,会按照文件名中的后缀来确定文件类型以及该文件的的默认打开程序.但是这个习俗并不通用.在一些其他系统上比如OSX,Unix,Linux等就没有这种的习惯,一般不会对文件类型做这么精确的分类.
文件由于被操作系统进行了管理,所以根据不同的用户,会赋予用户不同的对待该文件的权限,一般地可以认为有可读,可写,可执行权限.
Java中操作文件
在Java中通过java.io.File类来对一个文件和目录就进行描述.注意,有File对象,并不代表真实存在该文件.
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 | 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() | 判断用户是否对文件有可写权限 |
实例一:
public class IODemo1 {
public static void main(String[] args) throws IOException {
File file = new File("./test.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());
}
}
实例二:
public class IODemo2 {
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
System.out.println(file.delete());
}
}
实例三:
public class IODemo3 {
public static void main(String[] args) throws InterruptedException {
File file = new File("./test.txt");
file.deleteOnExit();
Thread.sleep(5000);
}
}
实例四:
public class IODemo {
public static void main(String[] args) {
File file = new File(".");
String[] str = file.list();
System.out.println(Arrays.toString(str));
File[] files = file.listFiles();
System.out.println(Arrays.toString(files));
}
}
实例五:
public class IODemo4 {
public static void main(String[] args) {
File file = new File("./test.txt");
File file2 = new File("./test2.txt");
// file.mkdir();
// file.mkdirs();
file.renameTo(file2);
}
}
文件的读写 - 数据流
InputStre
修饰符及返回值类型 | ⽅法签名 | 说明 |
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) | 利⽤⽂件路径构造⽂件输⼊流 |
public class IODemo5 {
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("test2.txt")) {
while(true) {
//read()
/*int n = inputStream.read();
if(n == -1) {
return;
}
System.out.printf("%c", n);*/
//read(byte[])
byte[] buffer = new byte[1024];
int n = inputStream.read(buffer);
if(n == -1) {
return;
}
System.out.println(Arrays.toString(buffer));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
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() | 重要:我们知道 I/O 的速度是很慢 的,所以,⼤多的 OutputStream 为了减少设备操作的次数,在写数 据的时候都会将数据先暂时写⼊内 存的⼀个指定区域⾥,直到该区域 满了或者其他指定条件时才真正将 数据写⼊设备中,这个区域⼀般称 为缓冲区。但造成⼀个结果,就是 我们写的数据,很可能会遗留⼀部 分在缓冲区中。需要在最后或者合 适的位置,调⽤flush(刷新)操 作,将数据刷到设备中。 |
OutputStream同样是一个抽象类,要使用还需要具体的实现类.我们现在还是只关心写入文件中,所以使用FileoutputStream
FIleOutputStream
实例:
public class IODemo6 {
public static void main(String[] args) {
try(OutputStream outputStream = new FileOutputStream("test2.txt")) {
byte[] buffer = new byte[]{12,65,76,78,90,89};
outputStream.write(buffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Scanner
Scanner这个类也可以帮助我们进行字符读取
实例:
public class IODemo7 {
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("test2.txt")) {
Scanner scanner = new Scanner(inputStream);
while(scanner.hasNext()) {
String s = scanner.next();
System.out.println(s);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
小程序练习
扫描指定目录,找到指定文件路径
import java.io.File;
import java.util.Scanner;
public class IODemo1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要扫描的目录: ");
String rootPath = scanner.next();
System.out.println("请输入你要查找的文件: ");
String fileName = scanner.next();
File file = new File(rootPath);
if(!file.isDirectory()) {
System.out.println("输入的目录不合法");
return;
}
scanDir(file, fileName);
}
private static void scanDir(File file, String fileName) {
File[] files = file.listFiles();
if(files == null) {
return;
}
for(File f : files) {
System.out.println("遍历到: " + f.getAbsolutePath());
//如果是普通文件
if(f.isFile()) {
if(fileName.equals(f.getName())) {
System.out.println("需要查找的文件路径: " + f.getAbsolutePath());
}
//如果是子目录
}else if(f.isDirectory()) {
scanDir(f, fileName);
}else {
;
}
}
}
}
文件复制
import java.io.*;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* Description:
* User: sun杰
* Date: 2024-01-19
* Time: 15:43
*/
public class IODemo3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入源文件");
String srcPath = scanner.next();
File srcfile = new File(srcPath);
if(!srcfile.isFile()) {
System.out.println("你输入的路径不合法");
return;
}
System.out.println("请输入目标文件");
String destPath = scanner.next();
File destfile = new File(destPath);
if(!destfile.getParentFile().isDirectory()) {
System.out.println("你输入的路径不合法");
return;
}
try(InputStream inputStream = new FileInputStream(srcfile);
OutputStream outputStream = new FileOutputStream(destfile)) {
while(true) {
//将源文件的内容读取到Buffer数组中
byte[] buffer = new byte[1024];
int n = inputStream.read(buffer);
if(n == -1) {
break;
}
//将读到的内容写到目标文件中
outputStream.write(buffer, 0 , n);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
扫描指定目录,通过文件内容来寻找指定文件
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
import java.util.zip.InflaterOutputStream;
/**
* Created with IntelliJ IDEA.
* Description:
* User: sun杰
* Date: 2024-01-19
* Time: 16:08
*/
public class IODemo4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要扫描的目录: ");
String fileName = scanner.next();
System.out.println("请输入需要查找的词");
String word = scanner.next();
File rootFile = new File(fileName);
if(!rootFile.isDirectory()) {
System.out.println("你输入的路径不合法");
return;
}
scanDir(rootFile, word);
}
public static void scanDir(File rootFile, String word) {
File[] files = rootFile.listFiles();
if(files == null) {
return;
}
for(File f : files) {
if(f.isFile()) {
searcewordFile(f, word);
}else if(f.isDirectory()) {
scanDir(f, word);
}else {
;
}
}
}
private static void searcewordFile(File f, String word) {
try(InputStream inputStream = new FileInputStream(f)) {
StringBuilder stringBuilder = new StringBuilder();
while(true) {
byte[] buffer = new byte[1024];
int n = inputStream.read(buffer);
if(n == -1) {
break;
}
String s = new String(buffer, 0, n);
stringBuilder.append(s);
}
if(stringBuilder.indexOf(word) == -1) {
return;
}
System.out.println("找到了,路径为: " + f.getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}