目录
文件指的是硬盘上的文件
硬盘和内存相比:
速度上:内存比硬盘快很多
空间上:内存空间比硬盘小
成本:内存比硬盘贵
持久化:内存掉电后数据丢失,硬盘掉电后数据还在
路径:
(每个目录用‘ / ’分割)
绝对路径:从盘符开始,一层一层往下找
相对路径:从给定的某个目录出发,一层一层往下找
(./表示当前目录,../表示当前目录的上级目录)
文件操作:
文件系统操作:创建文件、删除文件、重命名文件、创建目录......
文件内容操作:针对文件内容的读和写
文件系统操作:
Java数据库给我们提供了File类,是硬盘上文件的抽象表示(通过操作内存中的对象间接影响硬盘上的文件情况)
构造File对象:可以用绝对路径或者相对路径
File提供的相关方法:
import java.io.File;
import java.io.IOException;
public class demo1 {
public static void main(String[] args) throws IOException {
File file=new File("./cat.jpg");
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());
}
}
执行结果
.
cat.jpg
.\cat.jpg
C:\Users\00000\IdeaProjects\basic-code\.\cat.jpg
C:\Users\00000\IdeaProjects\basic-code\cat.jpg
文件内容操作:
针对文本文件,提供了一组类叫字符流(比如:Reader和Writer)
读写的基本单位是字符
针对二进制文件,提供了一组类叫字节流(比如:InputStream和OutputStream)
读写的基本单位是字节
用来输入的是:Reader和InputStream
用来输出的是:Writer和OutputStream
InputStream的使用方法:
InputStream是一个抽象类,不能直接实例化,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,我们现在只关心从文件中读取,所以使用 FileInputStream。
InputStream inputstream = new FileInputStream();//指定要读的路径
让当前这个变量和硬盘上的文件关联起来,相当于有了遥控器
inputstream.close();//非常重要!!
示例:
public class demo4 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("d:/demo.txt")){
//资源会在try代码块执行完毕并自动执行close关闭操作
while (true) {
//读文件,read一次返回的是一个字节
int b = inputStream.read();
if (b == -1) {
break;//读到末尾,循环结束
}
System.out.printf("%x\n",b);
}
}
}
}
执行结果:
读出的是每个字符的ASCII码
read和write一次也可以读多个字节,用byte[ ]来表示
try (InputStream is = new FileInputStream("d:/demo.txt")) {
byte[] buf = new byte[1024];
while (true) {
int n = is.read(buf);
if (n == -1) {
break;
}
// buf 的 [0, n) 表示读到的数据,按业务进行处理
}
}
一行一行读,并且输出中文:
scanner套上inputstream
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class demo5 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("d:/demo.txt")){
try (Scanner scanner=new Scanner(inputStream,"UTF-8")){
while (scanner.hasNext()){
String s=scanner.next();
System.out.println(s);
}
}
}
}
}
执行结果:
练习:
扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
import java.io.*;
import java.util.Scanner;
public class demo6 {
public static void main(String[] args) throws IOException {
Scanner scanner =new Scanner(System.in);
//让用户指定要搜索的根目录
System.out.println("请输入要扫描的根目录");
File rootDir=new File(scanner.next());
if(!rootDir.isDirectory()){
System.out.println("输入错误,您输入的目录不存在");
return;
}
//让用户输入要查询的词
System.out.println("请输入要查询的词");
String word=scanner.next();
//递归的遍历目录查找
scanDir(rootDir,word);
}
private static void scanDir(File rootDir, String word) throws IOException {
//列出rootDir中的内容,没有则直接结束递归
File[] files=rootDir.listFiles();
if(files==null){
return;
}
//目录中有内容,就遍历目录中的每个目录或者文件
for (File f: files) {
System.out.println("当前搜索到:"+f.getAbsolutePath());
//如果是普通文件,则打开文件读取内容,看是否包含要查找的关键词
if(f.isFile()){
String content=readFile(f);
if(content.contains(word)){
System.out.println(f.getAbsolutePath()+"包含要查找的词");
}
}
//如果是目录则进行递归操作
if(f.isDirectory()){
scanDir(f,word);
}else {
//如果不是目录或者文件则直接跳过
continue;
}
}
}
private static String readFile(File f) throws IOException {
//用字符流读取字符串
//要读取文件的整个内容全部返回出来,所以选择StringBuilder
StringBuilder stringBuilder=new StringBuilder();
try (Reader reader=new FileReader(f)){
//一次读一个字符,放入stringBuilder
while (true) {
int c=reader.read();
if(c==-1){
break;
}
stringBuilder.append((char) c);//int转为char
}
}
//统一转为string
return stringBuilder.toString();
}
}
执行结果: