文件IO操作笔记
目录
1.文件操作
2.File类
3.流(针对文件内容操作读写)
3.1 InputStream
3.2 Scanner
4.练习
1.文件操作
狭义文件就是存储在硬盘上的数据,以“文件”为单位
广义上的文件就是操作系统负责管理硬件资源,操作系统(Linux)一般都会将这些资源统一抽象成“文件”来管理
绝对路径:C:\Program Files (x86)\Origin\Origin.exe
相对路径:写相对路径必须知道基准路径
文件操作是属于 操作系统层面的;提供一些API接口
不同的操作系统,提供的API不同
但是Java就在JVM中把不同系统的操作文件的API封装,这样我们就可以使用Java中的库来实现文件操作
2.File类
Java中 通过 java.io.File 类对一个文件(包括目录)进行抽象的描述。注意的是:有File对象,并不代表真实的存在该文件
File类的常用方法
Demo1 get方法
package 文件io;
import java.io.File;
import java.io.IOException;
public class FileGet {
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());
}
}
Demo2 普通文件的创建、删除
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.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
}
}
Demo3 普通文件的删除
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现象
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.delete());
System.out.println(file.exists());
}
}
Demo4 观察 deleteOnExit 的现象
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现象
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
file.deleteOnExit();
System.out.println(file.exists());
}
}
Demo5 观察目录的创建
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File dir = new File("some-dir"); // 要求该目录不存在,才能看到相同的现象
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdir());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
}
mkdir 创建单层目录 mkdirs 创建多层目录
Demo6 观察文件重命名
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求 some-file.txt 得存在,可以是普通文件,可以是目录
File dest = new File("dest.txt"); // 要求 dest.txt 不存在
System.out.println(file.exists());
System.out.println(dest.exists());
System.out.println(file.renameTo(dest));
System.out.println(file.exists());
System.out.println(dest.exists());
}
}
3.流(针对文件内容操作读写)
Java标准库,在“流”的概念上,提供了一组类,完成读写文件的操作
这组类,分为两种( 这两种都是抽象类,不能实例化)
a)字节流(以字节为基本单位),适用于二进制文件
InputStream 读 OutputStream 写
b)字符流(以字符为基本单位),适用于文本文件
Reader 读 Writer 写
上面的这些都是 父类,
在标准库中,给这些父类还提供了各种子类的实现,以适应各种不同常见下的读写需求
InputStream --> FIleInputStream OutputStream --> FileOutputStream
Reader --> FileReader Writer --> FileWriter
3.1 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() | 关闭字节流 |
int read(byte[] b) 和 int read(byte[] b, int off, int len) 是把读到的内容放到参数字节b数组中
参数b用来存放方法读取到的结果
需要注意正常情况下,对于方法来说,参数表示的是“输入信息”,返回值才是“输出信息”
但此时,是用参数b来作为存放输出结果的内容,b称为是“输出型参数”
InputStream read()读取文件中的字节数据
public class Demo {
public static void main(String[] args) throws IOException {
//打开文件
InputStream inputStream = new FileInputStream("./bbb.txt");
while(true) {
int b = inputStream.read();
if(b == -1) {
break;
}
System.out.println(b);
}
//关闭文件
inputStream.close();
}
}
OutputStream write()写文件
需要注意的是,使用OutputStream写文件时,只要打开文件成功,就会把文件原有内容清空,重新给进写
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();
}
}
}
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
byte[] b = new byte[] {
(byte)'G', (byte)'o', (byte)'o', (byte)'d'
};
os.write(b);
// 不要忘记 flush
os.flush();
}
}
}
3.2 Scanner
利用Scanner进行字符读取
构造方法 | 说明 |
Scanner(InputStream is,String charset) | 使用 charset 字符集进行 is 的扫描读取 |
import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 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);
}
}
}
}
}
4.练习
练习一
扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要 删除该文件
package 文件io;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
//扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件
public class Demo {
public static void main(String[] args) throws IOException {
//1.让用户输入 要扫描的路径+要查找的关键词
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要扫描的路径:");
File rootDir = new File(scanner.next());
//用isDirectory判断一下rootDir是不是目录
if (!rootDir.isDirectory()){
System.out.println("您输入的目录不存在!");
return;
}
System.out.println("请输入要搜索的关键词:");
String toDelete = scanner.next();
//2. 遍历目录,找到名字匹配的文件
scanDir(rootDir,toDelete);
}
//递归遍历
private static void scanDir(File rootDir,String toDelete) throws IOException {
System.out.println("当前访问:"+rootDir.getCanonicalPath());
File[] files = rootDir.listFiles();
if (files == null) {
//说明 rootDir 是一个空目录
return;
}
//如果目录不为空 则循环遍历
for (File f:files) {
if (f.isDirectory()){
//继续递归调用
scanDir(f,toDelete);
}else {
//不是目录 是普通文件 判断文件名是否是要查找的,是否要进行删除
checkDelete(f,toDelete);
}
}
}
private static void checkDelete(File f,String toDelete) throws IOException {
//看一下文件中是否含由要删除的文件 toDelete
if (f.getName().contains(toDelete)){
System.out.println("这个关键字"+toDelete+"被"+f.getCanonicalPath()+"包含,是否要进行删除?(Y/N)");
Scanner scanner = new Scanner(System.in);
String choice = scanner.next();
if (choice.equals("Y") || choice.equals("y")) {
f.delete();
System.out.println("删除成功");
}
}
}
}
练习二
进行普通文件的复制
package 文件io;
import java.io.*;
import java.util.Scanner;
//进行普通文件的复制
public class Demo2 {
public static void main(String[] args) {
//1.先输入要复制那个文件 和 将文件复制到那里去(目标文件)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入源文件:");
//使用File的作用是可以判断文件是否存在
File srcFile = new File(scanner.next());
System.out.println("请输入目标文件");
File destFile = new File(scanner.next());
if (srcFile.isFile()) {
System.out.println("输入的源文件有误!");
return;
}
//getParentFile() 如果文件不存在就抛出异常
if(!destFile.getParentFile().isDirectory()) {
System.out.println("输入的目标文件有误!");
return;
}
//打开源文件 按照字节读取内容 依次写入目标文件中
try {
InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(destFile);
//读 src 的每一个字节 写入到dest中
while (true) {
int ret = inputStream.read();
//如果读到 -1 就结束
if (ret == -1){
break;
}
outputStream.write(ret);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
练习三
扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
package 文件io;
import java.io.*;
import java.util.Scanner;
//扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
public class Demo3 {
public static void main(String[] args) throws IOException {
//输入路径和要查找的关键词
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要扫描的路径:");
File rootDir = new File(scanner.next());
System.out.println("请输入要查询的关键词:");
String toFind = scanner.next();
//递归进行扫描目录
scanDir(rootDir,toFind);
}
private static void scanDir(File rootDir,String toFind) throws IOException {
File[] files = rootDir.listFiles();
if (files == null){
return;
}
for (File f:files){
if (f.isDirectory()){
scanDir(f,toFind);
}else {
checkFile(f,toFind);
}
}
}
private static void checkFile(File f,String toFind) throws IOException {
//先检查文件名
if (f.getName().contains(toFind)){
System.out.println(f.getCanonicalPath()+"文件名中包含"+toFind);
}
//检查文件内容
InputStream inputStream = new FileInputStream(f);
StringBuilder stringBuilder = new StringBuilder();
Scanner scanner = new Scanner(inputStream);
while (scanner.hasNextLine()) {
stringBuilder.append(scanner.nextLine()+"\n");
}
if (stringBuilder.indexOf(toFind) > -1){
System.out.println(f.getCanonicalPath()+"文件内容包含"+toFind);
}
}
}