IO学习笔记之一
一、File文件
1.概述:
可以理解为文件名和文件夹名称。
注意:
文件名其实就是文件的完整路径,例如:C:\Windows\system32 \Boot\winload.exe,这个整体是一个文件名。
文件夹名其实就是文件夹的路径,例如:C:\Windows,表示文件夹名
File既可以代表文件名也可以代表文件夹名。
2.构造方法:
public File(String pathname)//根据给定的文件路径或者目录路径,创建一个file对象
public File(String parent, String child)//根据给定的目录路径,和给定子目录路径或者文件路径,创建一个File对象
public File(File parent, String child)//根据给定的父File对象,和给定的子目录路径或者文件路径,创建一个File对象。
3.常用方法:
3.1创建功能
public boolean mkdir()//创建指定的单层文件夹,如果该文件不存在则创建该文件,并返回true;如果该文件存在,就不创建返回false
public boolean mkdirs()//创建多层文件。
public boolean createNewFile()//如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false。
测试案例:
public class FileMethodDemo {
public static void main(String[] args) throws IOException {
//创建文件
//1指定文件路径,创建文件对象
//注意:指定的文件路径必须事先存在,否则会创建失败
File file = new File("D:\\lee\\hello.txt");
//2调用File类中的方法,创建具体文件
booleanflag = file.createNewFile();
//打印是否创建成功
System.out.println(flag);
//创建单层文件夹
//1指定文件夹路径,创建文件夹对象
//注意:指定的文件夹路径必须事先存在,否则会创建失败
File file2 = new File("d:\\lee\\bb");
//调用File类中的方法创建具体文件夹
booleanflag2 = file2.mkdir();//创建单层文件夹
System.out.println(flag2);
//创建多层文件夹
//1指定文件夹路径,创建文件夹对象
//注意:指定的文件夹路径必须事先存在,否则会创建失败
File file3 = new File("d:\\lee\\111\\222");
//调用File类中的方法创建文件夹
booleanflag3 = file3.mkdirs();//创建多层文件夹
System.out.println(flag3);
//注意:在创建文件或问价夹时,不要调错方法以免引起误解,如下:
//把文件路径写成文件夹路径了,避免出现此情况
File file4 = new File("d:\\lee\\lee");
booleanflag4 = file4.createNewFile();//创建文件
System.out.println(flag4);
File file5 = new File("d:\\lee\\xiang.txt");
//把文件夹路径写成文件路径了,避免出现此情况
booleanflag5 = file5.mkdir();//创建文件夹
System.out.println(flag5);
}
}
输出结果:
true
true
true
true
true
计算机D盘显示结果如图1所示。由图1可知,创建文件还是创建文件夹不是由文件对象决定的,而是由对象调用具体的方法决定的。
图1
3.2删除功能
public booleandelete()//删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。
测试案例:
public class FileMethodDemo2 {
public static void main(String[] args) {
//删除文件
//指定文件路径,创建文件对象
//指定的文件路径必须存在,否则会创建失败
File file = new File("D:\\lee\\hello.txt");
//调用file类中的对应的方法
//注意:通过eclipse删除文件时,不经过回收站,直接删除。
booleanflag = file.delete();
System.out.println(flag);
//删除文件夹
//指定文件夹路径,创建文件夹对象
File file2 = new File("D:\\lee\\bb");
//调用相关删除方法
//注意:只能删除空文价夹,通过eclipse删除文件夹时,不经过回收站,
直接删除
System.out.println(file2.delete());
//要删除带内容的文件夹,只能用递归的方式先把文件夹中的所有文件或文
件夹都删除后,才能删除最外层文件夹
}
}
3.3重命名功能
相对路径:不带盘符的就叫相对路径,例如:lee\\hello.txt
绝对路径:带盘符的就叫绝对路径,例如:D:\\lee\\hello.txt
public boolean renameTo(File dest)//重新命名此抽象路径名表示的文件。
注意:
在eclipse中如果写的是相对路径,那么会在当前项目的跟目录创建对应的文件夹或文件
如果源File对象与目的地File对象在同一个文件夹,是重命名功能。
如果源File对象与目的地File对象不在同一个文件夹,是剪切+重命名功能。
测试案例:
public class FileMethodDemo3 {
public static void main(String[] args) throws IOException {
File srcName = new File("d:\\lee\\123.txt");
//指定文件路径,创建重命名后的文件对象
//在相同文件夹下是重命名文件
//File destName = new File("d:\\lee\\456.txt");
//在不同文件夹下是剪切+重命名功能
File destName = new File("c:\\456.txt");
System.out.println(srcName.renameTo(destName) );
}
}
3.4获取功能:
public FilegetAbsoluteFile()//获取File对象的绝对路径
public String getPath()//获取File对象的路径 (相对路径)。
public String getName()//获取File对象的名字。
public long lastModified()//获取file对象最后修改时间
public long length()//获取文件长度
测试案例:
public class FileMethodDemo4{
public static void main(String[] args) {
//指定文件路径,创建文件对象
File file = new File ("d:\\lee\\456.txt");
File file2 = new File ("456.txt");
//调用File中的方法,获取文件的绝对路径,返回file对象
System.out.println("绝对路径:"+file.getAbsolutePath());
//调用File中的方法,获取文件的相对路径,返回String字符串
System.out.println("相对路径:"+file2.getPath());
//获取文件名
System.out.println("文件名:"+file.getName());
//最后修改时间,返回long类型时间
long lastModified = file.lastModified();
//把时间转换成日期
Date d = new Date(lastModified);
System.out.println("最后修改时间:"+d);
//获取问价长度
System.out.println("文件长度:"+file.length());
}
}
输出结果:
绝对路径:d:\lee\456.txt
相对路径:456.txt
文件名:456.txt
最后修改时间:WedMay 20 23:22:43 CST 2015
文件长度:11
3.5判断功能:
public boolean isDirectory()//判断是否是文件夹。
public booleanisFile()//判断是否是文件。
public booleanexists()//判断File对应的文件或文件夹是否存在。
public booleancanRead()//判断文件是否可读
public booleancanWrite()//判断文件是否可写
public booleanisHidden()//判断文件是否为隐藏
测试案例:
public class FileMethodDemo5{
public static void main(String[] args) {
//指定文件路径,创建文件对象
File file = new File("d:\\lee\\456.txt");
//判断是否是文件夹
System.out.println("isDirectory:" +file.isDirectory());
//判断是否是文件
System.out.println("isFile:" +file.isFile());
//判断文件是否存在
System.out.println("exists:" +file.exists());
//判断文件是否可读
System.out.println("canRead:" +file.canRead());
//判断文件是否可写
System.out.println("canWrite:" +file.canWrite());
//判断文件是否为隐藏
System.out.println("isHidden:" +file.isHidden());
}
}
输出结果:
isDirectory:false
isFile:true
exists:true
canRead:true
canWrite:true
isHidden:false
图2是456.txt文件的属性
图2
3.6高级获取功能:
public staticFile[] listRoots()//列出可用的文件系统根
public String[]list()//返回指定File对象所代表的文件夹中,所有的文件夹和文件的名称。
public File[] listFiles()//返回指定File对象所代表的文件夹中, 所有的文件夹和文件的File对象 (绝对路径)。
测试案例:
public class FileMethodDemo6{
public static void main(String[] args) {
//public static File[] listRoots()
System.out.println("可用的文件系统根");
File[] listRoots = File.listRoots();
System.out.println(Arrays.toString(listRoots));
//指定文件夹中所有问价和文件夹
System.out.println("指定文件夹中所有文件和子文件夹");
File file = new File("d:\\lee");
String[] list = file.list();
for (inti = 0; i < list.length; i++) {
System.out.println(list[i]);
}
System.out.println("指定文件夹中所有文件和文件夹的绝对路径");
File[] listFiles = file.listFiles();
for (inti = 0; i < listFiles.length; i++) {
System.out.println(listFiles[i]);
}
}
}
输出结果:
可用的文件系统根
[C:\,D:\]
指定文件夹中所有文件和子文件夹
111
222.xlsx
333.pptx
456.txt
指定文件夹中所有文件和文件夹的绝对路径
d:\lee\111
d:\lee\222.xlsx
d:\lee\333.pptx
d:\lee\456.txt
5.综合练习:
5.1判断d盘某目录下是否有后缀名为.jpg的文件,如果有就输出此文件名称,普通方式。
分析:
1).指定文件夹路径,创建文件夹对象
2).获取当前目录下所有File对象
3).遍历每一个file对象
4).获取file对象的文件名
5).判断该文件名是否以.jpg结尾
注意:该方法不能避免把文件夹“555.jpg”误当成文件的情况
测试代码:
public class FileTest {
public static void main(String[] args) {
//1:指定文件夹路径,创建File对象
File file = new File("d:\\lee");
//2: 获取当前目录下所有的File对象
File[] files = file.listFiles();
//3:遍历,得到每一个File对象
for (Filef : files) {
//得到File对象的名字
String name = f.getName();
//用String中的方法判断是否以.jpg结尾
if (name.endsWith(".jpg")) {
System.out.println(name);//打印该文件名
}
}
}
}
输出结果:
555.jpg
history.jpg
psb.jpg
xiao.jpg
图3是D盘lee下的所有文件,该方法把文件夹“555.jpg”当成文件了。
图3
5.2判断d盘某目录下是否有后缀名为.jgp的文件,如果有就输出此文件名称,过滤器方式。推荐使用
测试代码:
public classFileNameFilterDemo {
public static void main(String[] args) {
//创建File对象
File file = new File("d:\\lee");
//获取所有.java结尾的File文件,过滤器方式
File[] files = file.listFiles(new FilenameFilter(){
//重写接口中的方法,匿名内部类对象方式
public boolean accept(File dir, Stringname) {
//dir:文件目录;name:文件名称
//把dir和name封装成file对象
File file = new File(dir,name);
//判断是否是文件,避免出现把文件夹“555.jpg”当成文件的情况
booleanflag1 = file.isFile();
//判断文件名称是否是 java结尾
booleanflag2 = name.endsWith(".jpg");
returnflag1 && flag2;//两个同时满足
}
});
//遍历
for (Filef : files) {
System.out.println(f);
}
}
}
输出结果:
d:\lee\history.jpg
d:\lee\psb.jpg
d:\lee\xiao.jpg
图4是D盘lee文件夹下的所有文件,过滤掉了文件夹“555.jpg”。
图4
二、递归:
1.概述:在方法的内部,调用本方法。通俗的讲就是一个方法自己调用自己
在一个程序中有n个相同的方法在运行,只不过每个方法的参数不同。
递归是用栈实现的
递归满足的条件:
1、递归必须的有一个明确的终止条件
2、该方法所处理的数据规模必须在递减
3、构造方法不能递归使用
递归和循环的关系:
理论上所有的循环都可以转换成递归,但是用递归能解决的问题不一定能用循环解决,例如“树”,汉诺塔游戏等。
递归的特点:代码简洁,易于理解,执行速度慢,栈空间开销大
循环的特点:代码简洁,不易理解,执行速度快,存储空间小。
测试案例:
1.求一个数的阶乘,例如5!的阶乘。
分析:
因为:5! = 5 x 4! ,4!= 4 x 3!,3!= 3 x 2! ,2!= 2 x 1!,1! = 1。
所以:2! = 2 x 1,3! = 3 x 2,4! = 4 x 6,5! = 5 x 24 = 120.
图5为5的阶乘的图解过程。
图5
测试代码:
public class DiguiDemo {
public static void main(String[] args) {
int sum = jc(5);
System.out.println(sum);
}
//计算阶乘
public static int jc(intn) {
if (n == 1) {
return 1;
} else {
returnn * jc(n-1);
}
}
}
输出结果:5! = 120
图6是程序执行的示意图。
图6
2.斐波那契数列,从第三项开始每一个数是前两个数之和,求第N个数的值
序号:1 2 3 4 5 6 7
数值:1 1 2 3 5 8 13 ……
分析:
n == 1,值1
n == 2,值1
n == 3,值2:sum(n-1)+sum(n-2)
n == 4,值3:sum(n-1)+sum(n-2)
测试代码:
public class DiguiTest2 {
public static void main(String[] args) {
intn = 7;
intnum = func(n);//n=5,7,20
System.out.println("第"+n+"个数的值是:"+num);
}
public static int func(intn) {
if (n == 1 ||n == 2) {
return 1;
} else {
returnfunc(n-1) + func(n-2); //自己调用自己
}
}
}
输出结果:第7个数的值是:13
3.用递归遍历指定文件夹中avi格式的文件。
分析:
1).把指定的文件夹封装成File对象
2).获取该文件夹对象中所有的File对象(listfiles()方法)
3).获取到每一个file对象,增强for循环
4).判断这个file对象是否是文件夹
是:递归操作,回到步骤二
否:判断当前文件是否以.avi结尾。
是avi文件:打印文件路径名称
不是avi文件:无操作。
测试代码:
public class DiguiTest3 {
public static void main(String[] args) {
//1:指定文件夹路径,创建file对象
File file = new File("d:\\avi");
//2: 获取到当前目录中所有的File对象,并判断
getFiles(file);
}
//获取到当前目录中所有的File对象
public static void getFiles(File pathFile) {
//如果文件为空,就结束程序
if (pathFile ==null) {
return ;
}
//获取到当前目录中所有的File对象
File[] files = pathFile.listFiles();
//3:遍历,获取到每一个File对象
for (Filefile : files) {
//4:判断这个File对象是否是文件夹
if (file.isDirectory()) {
//递归操作:如果是文件夹,回到步骤2
getFiles(file);
} else {//如果不是文件夹
//判断当前文件是否是.avi文件
if (file.getName().endsWith(".avi")) {
System.out.println(file.getAbsolutePath());
}
}
}
}
}
输出结果:
d:\avi\01.01_计算机基础知识(计算机概述).avi
d:\avi\01.02_计算机基础知识(计算机语言).avi
d:\avi\01.03_计算机基础知识(人机交换方式).avi
d:\avi\01.04_计算机基础知识(键盘快捷键介绍).avi
d:\avi\111\01计算机基础知识(计算机概述).avi
d:\avi\111\02计算机基础知识(计算机语言).avi
d:\avi\111\03计算机基础知识(人机交换方式).avi
d:\avi\111\222\7计算机基础知识(java的跨平台性).avi
d:\avi\111\222\8计算机基础知识(打开DOS控制台的方式).avi
4.用递归删除带内容的文件夹
分析:
1).指定文件夹路径,创建File对象
2).获取当前文件夹下所有File对象
3).遍历每一个file对象
4).判断当前File对象是否是文件夹
是:进入文件夹,回到步骤二
否:直接删除文件。
测试代码:
public class DiguiTest4 {
public static void main(String[] args) {
//1:封装目录File对象
File pathFile = new File("d:\\avi");
deletePathFiles(pathFile);
}
// 获取当前目录下,所有的FIle对象
public static voiddeletePathFiles(FilepathFile) {
//如果文件夹为空,程序退出
if (pathFile ==null) {
return;
}
//2:获取当前目录下,所有的FIle对象
File[] files = pathFile.listFiles();
//3:通过遍历,得到每一个File对象
for (Filefile : files) {
//4:判断当前File对象是否是文件夹
if (file.isDirectory()) {
//是文件夹,递归操作,回到步骤2
deletePathFiles(file);
} else {
//如果是文件就直接删除
//file.delete();
System.out.println(file.getAbsolutePath()+"---"+
file.delete());
}
}
//删除文件夹
System.out.println(pathFile.getAbsolutePath()+"---" +
pathFile.delete());
}
}
输出结果:
d:\avi\01.01_计算机基础知识(计算机概述).avi---true
d:\avi\01.02_计算机基础知识(计算机语言).avi---true
d:\avi\111\01计算机基础知识(计算机概述).avi---true
d:\avi\111\02计算机基础知识(计算机语言).avi---true
d:\avi\111\222\7计算机基础知识(java的跨平台性).avi---true
d:\avi\111\222\8计算机基础知识(打开DOS控制台的方式).avi---true
d:\avi\111\222---true
d:\avi\111---true
d:\avi\222.xlsx---true
d:\avi\333.pptx---true
d:\avi---true