目录
文件基础知识
相对路径与绝对路径
文件的读写
理解 "流","读","写"
Java的IO 流分为几种?
字节流如何转为字符流?
InputStream输入流
OutPutStream字节输出流
案例1 :扫描指定目录并删除文件
案例2 :普通文件的复制
案例3 :扫描指定目录并查找
冯诺依曼体系结构
文件是存储在硬盘上的.
硬盘与内存的区别:
文件是被操作系统管理的,操作系统内核有一个专门管理文件的模块---文件系统,java通过java.io.File 类针对文件系统进行了一系列的封装.有可读,可写,可执行权限 .注意,有 File 对象,并不代表真实存在该文件
从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描
述,而这种描述方式就被称为文件的绝对路径(absolute path)-----从根一直到目的地
以盘符开头的路径是"绝对路径"
我们可以从任意结点出发,进行路径的描述,而这种描述方式就被称为相对路径(relative path),相对于当前所在结点的一条路径 ------(从任意节点到目的地)
以.(当前路径) 或者 ..(当前路径的上一个路径) 开头的路径为"相对路径"
目录时间的分隔符可以是/(斜杠) 也可以是 \(反斜杠)
工作目录 :
文件构造方法
签名 |
说明 |
File(File parent, String |
根据父目录 + 孩子文件路径,创建一个新的 File 实例 |
File(String pathname) |
根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者 |
File(String parent, String |
根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用 |
文件里既可以是绝对路径也可以是相对路径
构造方法--根据文件创建文件实例
签名 |
说明 |
File(File parent, String |
根据父目录 + 孩子文件路径,创建一个新的 File 实例 |
File(String pathname) |
根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者 |
File(String parent, String |
根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用 |
文件常用方法
修饰符及返回 |
方法签名 |
说明 |
String |
getParent() |
返回 File 对象的父目录文件路径 |
String |
getName() |
返回 FIle 对象的纯文件名称 |
String |
getPath() |
返回 File 对象的文件路径 |
String |
getAbsolutePath() |
返回 File 对象的绝对路径 |
String |
getCanonicalPath() |
返回 File 对象的修饰过的绝对路径 |
boolean |
exists() |
判断 File 对象描述的文件是否真实存在 |
boolean |
isDirectory() |
判断 File 对象代表的文件是否是一个目录 |
boolean |
isFile() |
判断 File 对象代表的文件是否是一个普通文件 |
boolean |
createNewFile() |
根据 File 对象,自动创建一个空文件。成功创建后返 |
boolean |
delete() |
根据 File 对象,删除该文件。成功删除后返回 true |
void |
deleteOnExit() |
根据 File 对象,标注文件将被删除,删除动作会到 |
String[] |
list() |
返回 File 对象代表的目录下的所有文件名 |
File[] |
listFiles() |
返回 File 对象代表的目录下的所有文件,以 File 对象 |
boolean |
mkdir() |
创建 File 对象代表的目录 |
boolean |
mkdirs() |
创建 File 对象代表的目录,如果必要,会创建中间目 |
boolean |
renameTo(File |
进行文件改名,也可以视为我们平时的剪切、粘贴操 |
boolean |
canRead() |
判断用户是否对文件有可读权限 |
boolean |
canWrite() |
判断用户是否对文件有可写权限 |
get方法
判断的方法
创建删除文件
列表方法
目录方法
文件重命名
判断是否有权限
读写文件之前务必要打开文件,使用文件完毕之后,务必要及时关闭
我们在进行IO操作即输入和输出,将数据写入内存(输入),将内存数据输出到磁盘上(输出),输入输出数据过程类似水流简称IO流,对于数据处理的方式也有字节流和字符流
字节流用来操作二进制文件,字符流用来操作文本文件
java中提供了数据流来进行文件读写,分别是字符流和字节流
字节流 : outputStream(字节输出流) inputStream(字节输入流)
字符流 : writer(字符输出流) reader(字符输入流)
字节输入流转化成字符输入流通过inputStreamWriter 类的构造方法传入字节输入流对象inputStream
字节输出流转字符输出流通过outputStreamWriter类构造方法传入字节输出流对象outStream
inputStream是输入流用来从文件中数据读取到内存中.inputStream不能实例化需要使用FileInputStream来读取文件内容.
inputStream的使用方法介绍
FileinputStream直接可以指定文件路径,可以直接读取字节数据,也可以将数据读取到字节数组中.
关闭资源时释放什么资源???
答案是除了内存资源还有一个稀缺资源--文件描述符表
我们利用一个pcb控制块来描述一个进程,有一个重要的属性就是文件描述符表,文件描述符表相当于一个顺序表,表中每一个元素包括打开的文件,每个下标是文件描述符,当我们打开文件时,需要占据一个位置,关闭文件就释放一个位置,所以当一个进程关闭,而一直打开文件,没有释放,就会导致,再次打开文件时,导致打开文件失败.
使用try with resource 自动释放资源
try(InputStream inputStream = new FileInputStream("text.txt")){
}catch(IOException e){
e.printStackTrace();
}
inputStream的使用
//InputStream--- read()
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("text.txt")){
while(true){
int b = inputStream.read();
if(b==-1){
break;
}
System.out.printf("%c",b);
}
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("text.txt")){
byte[] bytes = new byte[1024];
while(true){
int len = inputStream.read(bytes);
if(len==-1){
break;
}
for(int i =0;i
一般使用inputStream来读取二进制文件,如果要读取文本文件可以使用String转化转成utf8,也可以使用reader来读取文本文件,还可以使用Scanner搭配inputStream使用(推荐使用)
String转换方法
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("text.txt")){
byte[] bytes = new byte[1024];
while(true){
int len = inputStream.read(bytes);
if(len==-1){
break;
}
for(int i =0;i
public static void main(String[] args) {
try(Reader reader = new FileReader("text.txt")){
char[] chars = new char[1024];
int len = reader.read(chars);
for(int i =0;i
public static void main(String[] args) {
try(InputStream inputStream = new FileInputStream("text.txt")){
Scanner scanner = new Scanner(inputStream);
while(scanner.hasNext()){
System.out.println(scanner.next());
}
}catch(IOException e){
e.printStackTrace();
}
OutputStream主要是将数据写入到文件中
FileOutputStream对象可以直接指定文件路径,可以输出字节数据,也可以输出字节数组数据
这里注意我们每次往文件中写入数据都是先将旧的文件数据清空,重新去写
outputStream方法使用介绍
write() : 将指定字节数据写入到文件中
write(byte[] b) : 将指定字节数组中的数据写入到文件中,返回实际写入的字节数
write(byte[] b,int off,int len) : 从off下标开始写入长度len个数据到文件中
close : 还是可以使用try with resource 自动关闭资源.
flush : 使用输出流千万不能把flush落下,可能会导致写不进去文件中.
由于IO设备读取速度非常慢,OutputStream为了减少读取次数就加入缓冲区,我们在读取时可能会导致一部分数据还没有写入到设备中,还留在缓冲区,所以我们就需要使用flush刷新一下,将数据刷新到设备中.
当然使用try也可以自动刷新
OutputStream方法使用
public static void main(String[] args) {
try(OutputStream outputStream = new FileOutputStream("text.txt")){
outputStream.write('h');
outputStream.write('e');
outputStream.write('l');
outputStream.write('l');
outputStream.write('o');
outputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
try(OutputStream outputStream = new FileOutputStream("text.txt")){
byte[] bytes = {'h','e','l','l','0','a','v','a'};
outputStream.write(bytes);
outputStream.flush();
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
try(OutputStream outPutStream = new FileOutputStream("text.txt")){
PrintWriter writer = new PrintWriter(outPutStream);
writer.println("hello,java");
writer.flush();
}catch(IOException e){
e.printStackTrace();
}
}
public class TestDemo1 {
/**
* 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要
* 删除该文件
* @param args
*/
public static void main(String[] args) {
System.out.println("请输入你要扫描的指定目录路径");
Scanner scan1 = new Scanner(System.in);
String s1 = scan1.next();
File rootPath = new File(s1);//创建路径实例
if(!rootPath.isDirectory()){
System.out.println("输入的并不是目录");
return;
}
System.out.println("请输入你要删除的文件");
Scanner scan2 = new Scanner(System.in);
String toDelete = scan2.next();
//开始扫描整个目录--找到与toDelete字符包含的文件
scanDir(rootPath,toDelete);
}
public static void scanDir(File rootPath,String toDelete){
//将文件目录的文件全部放到file数组里面
File[] files = rootPath.listFiles();
if(files==null||files.length==0) {
return ; //如果目录里面无文件,就不要扫描--退出
}
//开始扫描整个目录里的文件
for(File f : files){
if(f.isDirectory()){
//如果扫描的这个还是目录,那就继续深度优先便利--继续扫描此目录--直到找到文件为止
scanDir(f,toDelete);
}else {
//证明不是目录--是一个普通的文件---那我们看是否包含toDelete里的字符
//进而来判断是否要删除
tryDelete(f,toDelete);
}
}
}
public static void tryDelete(File f,String toDelete){
if(f.getName().contains(toDelete)){
try {
System.out.println("你是否要删除此路径下的文件Y/N ==>" + f.getCanonicalPath());
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
if(str.toLowerCase().equals("y")){
f.delete();
System.out.println("删除成功!!!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class TestDemo2 {
/**
* 进行普通文件的复制
* @param args
*/
public static void main(String[] args) {
System.out.println("请输入你要复制的源文件路径");
Scanner scanner = new Scanner(System.in);
String s1 = scanner.next();
File srcFile = new File(s1);
if(!srcFile.isFile()){
System.out.println("该文件不是普通的文件~~~");
return;
}
if(!srcFile.exists()){
System.out.println("该文件不存在~~~");
return;
}
System.out.println("请输入复制的目标路径~~~");
Scanner scan2 = new Scanner(System.in);
String s2 = scan2.next();
File destFile = new File(s2);
if(destFile.exists()){
System.out.println("该文件已经存在~~~");
return ;
}
//开始进行复制--读取源文件--复制到目标文件路径
try(InputStream inputStream = new FileInputStream(srcFile)){
try(OutputStream outputStream = new FileOutputStream(destFile)){
byte[] bytes = new byte[1024];
while(true){
int len = inputStream.read(bytes);
if(len==-1){
break;
}
outputStream.write(bytes);
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public class TestDemo3 {
/**
* 扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
* @param args
*/
public static void main(String[] args) {
System.out.println("请输入你要扫描的指定目录");
Scanner scan1 = new Scanner(System.in);
String root = scan1.next();
File file = new File(root);
if(!file.isDirectory()){
System.out.println("不是目录名~~~");
return;
}
System.out.println("请输入你要查找的内容");
Scanner scan2 = new Scanner(System.in);
String toFind = scan2.next();
scanDir(file,toFind);
}
public static void scanDir(File file ,String toFind){
File[] files = file.listFiles();
if(files==null||files.length==0){
// System.out.println("该目录里面没有文件~~~");
return;
}
for(File f : files){
if(f.isDirectory()){
scanDir(f,toFind);
}else {
tryFInd(f,toFind);
}
}
}
public static void tryFInd(File f, String toFind){
if(f.getName().contains(toFind)){
try {
System.out.println("找到与文件名相匹配的文件" + f.getCanonicalPath());
return;
} catch (IOException e) {
e.printStackTrace();
}
}
try(InputStream inputStream = new FileInputStream(f)){
byte[] bytes =new byte[1024];
StringBuilder res = new StringBuilder();
Scanner scan = new Scanner(inputStream);
while(scan.hasNext()){
res.append(scan.next());
}
if(res.indexOf(toFind)>=0){
System.out.println("找到了与文件内容相同的文件路径 " + f.getCanonicalPath());
return;
}
}catch(IOException e){
e.printStackTrace();
}
}
}