- 文件的分类
- 关于目录结构
- 文件路径
- 绝对路径
- 相对路径
- Java 中操作文件
- 文件的创建
- 文件的删除
- 单级目录的创建
- 多级目录的创建
- 文件的重命名
- 打印当前目录下所有的文件名
- 文件内容的读写 – 数据流
- FileInputStream
- FileOutputStream
- FileReader
- FileWriter
- 案例一
- 案例二
- 案例三
站在程序猿的角度来看,主要把文件分成两类:
- 文本文件
里面存储的是字符,虽说文本文件本质上也是存字节的,但是在文本文件中,相邻的字节在一起正好能构成一个个的字符。 ——此时字节和字节是相关联的
- 二进制文件
里面存储的是字节,但是字节和字节之间没啥关系。
针对这两种文件,在编程的时候是会存在差异的(●’◡’●)
如何判定一个文件是文本文件还是二进制文件?
一个很简单的方法就是:用记事本打开文件,如果打开之后是乱码,就是二进制文件;若不是乱码就是文本文件。
文本文件:
下面这个显示的乱码的就是二进制文件:
关于目录结构类似的,像我们日常中使用到的.txt,.c,.java都属于文本文件;.doc(里面保存的不是一个单纯的文本,而是一个富文本,文本中带有各种格式化的信息),.ppt,.exe,.zip,.class等都属于二进制文件。
计算机里,保存管理文件,是通过操作系统中的“文件系统”这样的模块来负责的。
文件系统中,一般是通过“树形”结构来组织磁盘上的目录和文件的。——此处的“树形”就是数据结构中学过的那个树,但是这里的树不是二叉树,而是N叉树。
示例图如下:
整体的文件系统就是这种树形结构。如果是一个普通文件,就是树的叶子节点;如果是一个目录文件,目录中就可以包含子树,这个目录就是非叶子节点。这个树每个节点上的子树都可以有N个,这就是一个N叉树了。
在操作系统中,就通过 “路径” 这样的概念,来描述一个具体文件/目录的位置的。
以盘符开头:D:谷歌chrome.exe
以 . 或者…(ps:此处是两个点,不知道为什么显示的是三个点ಥ_ಥ,下面同理)开头的 ,其中 . 表示当前路径 ,…表示当前路径的父目录(上级路径);谈到相对路径,必须要现有一个基准目录,相对路径就是从基准目录出发,然后按照一个什么样的路径找到的对应文件。
例如:以D:IDEAIntelliJ IDEA Community Edition 2021.3.2bin为基准目录,找到idea64.exe
./idea64.exe,此处的 . 就表示当前目录(基准目录)
还是以D:IDEAIntelliJ IDEA Community Edition 2021.3.2bin为基准目录,找到build.txt,那么就是…/build.txt。…就表示基准目录的上一级路径D:IDEAIntelliJ IDEA Community Edition 2021.3.2,再从这个路径中去找到build.txt这个文件。
Java 中操作文件注意: 即便是定位到同一个文件,如果基准目录不同,此时相对路径也不同。
代码示例如下:
package file;
import java.io.File;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
File f=new File("d:/test.txt");//绝对路径
System.out.println(f.getParent());//获取文件的父目录
System.out.println(f.getName());//获取文件名称
System.out.println(f.getPath());//获取文件路径(构造file的时候指定的路径)
System.out.println(f.getAbsolutePath());//获取绝对路径
System.out.println(f.getCanonicalPath());//获取绝对路径
System.out.println("==========================");
File f1=new File("./test.txt");//相对路径
System.out.println(f1.getParent());//获取文件的父目录
System.out.println(f1.getName());//获取文件名称
System.out.println(f1.getPath());//获取文件路径(构造file的时候指定的路径)
System.out.println(f1.getAbsolutePath());//获取绝对路径
System.out.println(f1.getCanonicalPath());//获取绝对路径
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
import java.io.IOException;
public class CreateFile {
public static void main(String[] args) throws IOException {
File file=new File("./test.txt");
System.out.println(file.exists());//查看文件是否存在
System.out.println("创建文件");
file.createNewFile();
System.out.println("创建成功");
System.out.println(file.exists());
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
public class DelFile {
public static void main(String[] args) {
File file=new File("./test.txt");
file.delete();
System.out.println(file.exists());//查看文件是否存在
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
public class SinFile {
public static void main(String[] args) {
File file=new File("./aaa");
file.mkdir();
System.out.println(file.isDirectory());//判断 File 对象代表的文件是否是一个目录
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
public class DbleFile {
public static void main(String[] args) {
File file=new File("./aaa/bbb/ccc/ddd");
file.mkdirs();
System.out.println(file.isDirectory());
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
public class ChangeNameFile {
public static void main(String[] args) {
File file=new File("./aaa");
File file1=new File("./AAA");
file.renameTo(file1);
}
}
结果图如下:
示例代码如下:
package file;
import java.io.File;
import java.util.Arrays;
public class ListFile {
public static void main(String[] args) {
File file=new File("./");
System.out.println(Arrays.toString(file.list()));//返回 File 对象代表的目录下的所有文件名
System.out.println(Arrays.toString(file.listFiles()));//返回 File 对象代表的目录下的所有文件,以 File 对象表示
}
}
结果图如下:
示例代码如下:
package file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
public class FIStream {
public static void main(String[] args) {
//构造方法中需要指定打开文件的路径
//此处的路径可以是绝对路径,也可以是相对路径,还可以是File对象
//由于上面的代码过于繁琐,下面的这个是改进版本
try(InputStream inputStream=new FileInputStream("d:/test.txt")){
//一次读取若干个字节
while(true){
byte[]buffer=new byte[1024];
int len=inputStream.read(buffer);//把读出来的参数放到buffer这个数组中
if(len==-1){
break;
}
for(int i=0;i
System.out.printf(buffer[i]+" ");
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
结果图如下:
示例代码如下:
package file;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FOStream {
public static void main(String[] args) {
try(OutputStream outputStream=new FileOutputStream("d:/test.txt")){
//一次写入多个字节
byte[]buffer=new byte[]{97,98,99,100,101};
outputStream.write(buffer);
}catch (IOException e){
e.printStackTrace();
}
}
}
结果图如下:
示例代码如下:
package file;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class FRead {
public static void main(String[] args) {
try(Reader reader=new FileReader("d:/test.txt")){
//按照字符来读
while (true){
char[]buffer=new char[1024];
int len=reader.read(buffer);
if(len==-1){
break;
}
// 如果这里传入的数组是byte数组, 还可以手动的指定一下 utf8 字符集避免乱码.
String str=new String(buffer,0,len);
System.out.println(str);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
结果图如下:
示例代码如下:
package file;
import java.io.*;
public class FORead {
public static void main(String[] args) {
try(Writer writer=new FileWriter("d:/test.txt")){
writer.write("yyqx");
}catch (IOException e){
e.printStackTrace();
}
}
}
结果图如下:
扫描一个指定的目录,并找到名称中包含指定字符的所有普通文件,并且根据用户的选择来判断是否要删除文件
代码如下:
package file;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Examp {
public static void main(String[] args) {
//1.先输入要扫描的目录,以及需要删除的文件名
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要扫描的路径:");
String rootDirPath=scanner.next();
System.out.println("请输入要删除的文件名:");
String DelName=scanner.next();
File rootDir=new File(rootDirPath);
if(!rootDir.isDirectory()){
System.out.println("输入的扫描路径有误!");
return;
}
//2.遍历目录,把指定目录中的所有文件和子目录都遍历一遍,从而找到要删除的文件
//通过这个方法来实现递归遍历并删除的操作
scanDir(rootDir,DelName);
}
public static void scanDir(File rootDir,String DelName){
//1.先列出rootDir中有哪些内容
File[]files=rootDir.listFiles();
if(files==null){
//说明rootDir是一个空目录
return;
}
//2.遍历当前列出的这个内容,看是否是普通文件,就检测文件名是否是要删除的文件
//如果是目录,就递归的进行遍历
for(File f:files){
if(f.isFile()){
//普通文件的情况
if(f.getName().contains(DelName)){
delete(f);
}
}else if(f.isDirectory()){
//如果还是个目录就递归的进行遍历
scanDir(f,DelName);
}
}
}
private static void delete(File f) {
try {
System.out.println(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("文件删除成功!");
}else {
System.out.println("文件取消删除");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果图如下:
进行普通文件的复制
代码如下:
package file;
import java.io.*;
import java.util.Scanner;
public class Examp1 {
public static void main(String[] args) {
//1.输入两个路径
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要拷贝的源路径");
String src= scanner.next();
System.out.println("请输入要拷贝的目标路径");
String dest= scanner.next();
File file=new File(src);
if(!file.isFile()){
System.out.println("输入的源路径不正确!");
return;
}
//此处不太需要检查目标文件是否存在,OutputStream写文件的时候能够自动创建不存在的文件
//2.读取源文件,拷贝到目标文件中
try(InputStream inputStream=new FileInputStream(src)){
try(OutputStream outputStream=new FileOutputStream(dest)){
while (true){
//把inputStream中的数据读出来,写入到outputStream中
byte[]buffer=new byte[1024];
int len=inputStream.read(buffer);
if(len==-1){
//读取完毕
break;
}
//写入的时候,不能把整个buffer都写进去,毕竟buffer可能只有一部分才是有效数据
outputStream.write(buffer,0,len);
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
结果图如下:
扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
代码如下:
package file;
import java.io.*;
import java.util.Scanner;
public class Examp2 {
public static void main(String[] args) throws IOException {
// 1. 输入要扫描的文件路径
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要扫描的路径:");
String rootDir=scanner.next();
System.out.println("请输入要查找的关键字:");
String word=scanner.next();
File file=new File(rootDir);
if(!file.isDirectory()){
System.out.println("您输入的路径有误!");
return;
}
// 2. 递归的进行遍历
scanDir(file,word);
}
public static void scanDir(File rootDir,String word) throws IOException {
// 1. 先列出 rootDir 中都有哪些内容
File []files=rootDir.listFiles();
if(files==null){
return;
}
for(File f:files){
// 2. 遍历每个元素, 针对普通文件和目录分别进行处理
if (f.isFile()){
// 针对文件进行内容查找
if(containWord(f,word)){
System.out.println(f.getCanonicalPath());
}
// 针对目录进行递归
}else if(f.isDirectory()){
scanDir(f,word);
}
}
}
private static boolean containWord(File f, String word) {
StringBuilder stringBuilder=new StringBuilder();
try(Reader reader=new FileReader(f)){
char[]buffer=new char[1024];
while (true){
// 把 f 中的内容都读出来, 放到一个 StringBuilder 中
int len= reader.read(buffer);
if(len==-1){
break;
}
// 把这一段读到的结果, 放到 StringBuilder 中
stringBuilder.append(buffer,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
// indexOf 返回的是子串的下标. 如果 word 在 stringBuilder 中不存在, 则返回下标为 -1
return stringBuilder.indexOf(word)!=-1;
}
}
结果图如下:


![[JavaEE]一文带你了解文件操作中的那些事儿——(含案例代码) [JavaEE]一文带你了解文件操作中的那些事儿——(含案例代码)](http://www.mshxw.com/aiimages/31/826142.png)
