File的基本应用
File对象的创建
File是对已存在的文件和未存在的文件进行对象封装,而我们创建File总共有三种方式,分别采用了File的三种构造方法,还有一个跨平台分隔符。如;
a) public File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新 File实例
b) public File(String parent,String child):根据 parent路径名字符串和 child路径名字符串创建一个新 File实例
c) public File(File parent,Stringchild):根据 parent抽象路径名和 child路径名字符串创建一个新 File实例。
d) public static final Stringseparator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串
我们演示下这三种构造方法和带跨平台的分隔符:
public static void startFile()
{
//将已存在和未存在文件封装成对象,
//第一种创建方式
Filef1=new File("a.txt");
//第二种创建方式,后面的文件是可变
Filef2=new File("c://abc//","1.txt");
//第三种创建方式,变量b是文件夹名
Filea=new File("c://zzz//");
Filef3=new File(a,"2.txt");
//跨平台的分隔符
Filef4=new File("c:"+File.separator+"3.txt");
sop(f1);
sop(f2);
sop(f3);
sop(f4);
}
publicstatic void sop(Object obj)
{
System.out.println(obj);
}
File常见方法
创建:
booleancreateNewFile():在指定的位置创建文件,如果该文件已经存在,则不创建,返回false。此方法和输出流不一样,输出流对象一建立就创建文件,而且文件存在会覆盖旧文件。
booleanmkdir():创建文件夹,即一级文件夹
booleanmkdirs():创建多级文件夹
删除:
booleandelete():删除失败则返回false。
voiddeleteOnExit():在程序退出时删除指定文件
判断:
boolean canExecute():用来判断应用程序是否可执行
booleanexists();:用来判断文件是否存在
booleanisFile:用来判断是否是文件
booleanisDirectory():用来判断是否是目录
booleanisHidden();用来判断是否是隐藏的文件
booleanisAbsolute():是否是绝对路径
获取信息:
String getName():返回由此抽象路径名表示的文件或目录的名称。
StringgetPath();获取一个相对路径名字符串。
String getParent();获取一个父目录的路径名字符串,该方法返回的是绝对路径的目录。如果不是,则相对路径返回null,如果相对路径中有上一层目录,则返回上一层目录
File getAbsoluteFile():获取绝对路径名
String getAbsolutePath():绝对路径名字符串。
以上两个可以互相转换的
long lastModified():获取文件最后一次被修改的时间。
long length():获取文件的长度
其他方法:
booleanrenameTo():对文件重命名,其有点类似剪切
对以上的几种方法,我们做以下演示来看看如何使用:
importjava.io.*;
classFileDemo
{
public static void main(String[] args)throws Exception
{
//startFile();
//method_create();
//Thread.sleep(3000);
//method_delete();
//method_judgement2();
//method_get();
method_rename();
}
public static voidmethod_create()throws IOException
{
File f=newFile("a.txt");
sop("是否创建:"+f.createNewFile());
File dir=newFile("abc");
sop("是否创建"+dir.mkdir());
File dirs =newFile("a//b//c//d");
sop("是否创建了多级文件夹:"+dirs.mkdirs());
}
public static void method_delete()
{
File f=newFile("a.txt");
//sop("是否删除:"+f.delete());
f.deleteOnExit();//运行退出后删除
}
public static void method_judgement1()
{
File f1=newFile("a.txt");
sop("判断是否存在此文件:"+f1.exists());
File f2=newFile(".");
sop("判断是否是可执行文件:"+f2.canExecute());
}
public static void method_judgement2(){
File f=newFile("a.txt");
//我们在判断是否是文件或者是文件夹前要判断是否存在
//使用exists()判断
if(f.exists()){
sop("是否是文件:"+f.isFile());
sop("是否是文件夹:"+f.isDirectory());
sop("是否是隐藏文件:"+f.isHidden());
}
//小知识:带盘符的是绝对路径
sop("是否是绝对路径:"+f.isAbsolute());
}
public static void method_get()
{
File f=newFile("D://JavaWork//a.txt");
sop("getName:"+f.getName());
sop("getPath:"+f.getPath());
sop("getParent:"+f.getParent());
sop("getAbsoluteFile"+f.getAbsoluteFile());
sop("getAbsolutePath"+f.getAbsolutePath());
long a=f.lastModified();
sop("最后一次文件修改时间:"+a);
long len=f.length();
sop("获取文件的长度:"+f.length());
}
public static void method_rename()
{
File f1=newFile("a.txt");
File f2=newFile("b.txt");
sop("是否重命名成功:"+f1.renameTo(f2));
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
文件列表:
static File[]listRoots():列出可用的文件系统根。
Stringp[]list():获取指定的目录下所有文件
File[]listFIles():获取指定目录下所有的文件和文件夹
String[]list(FilenameFilter filter):过滤目录下指定的文件后缀名
对于以上方法,我们再进行演示:
import java.io.*;
class FileDemo2
{
publicstatic void main(String[] args)
{
//method_listRoots();
//mthod_list();
//method_listFilter();
method_listFile();
}
publicstatic void method_listFile(){
Filef=new File("D://JavaWork//");
File[]file=f.listFiles();
for(Filef1:file){
System.out.println(f1.getName()+"....name:"+f1);
}
}
publicstatic void method_listFilter(){
Filef=new File("d://JavaWork//");
String[]str=f.list(new FilenameFilter(){
publicboolean accept(File dir,String name){
returnname.endsWith(".java");
}
});
for(Strings:str){
System.out.println(s);
}
}
publicstatic void mthod_list(){
Filef=new File("d://");
String[]s=f.list();
for(Stringstr:s){
System.out.println(str);
}
}
publicstatic void method_listRoots(){
File[]f=File.listRoots();
//增强for循环遍历
for(Filefiles:f){
System.out.println(files);
}
}
}
递归(Recursion)
当我们想列出指定目录下文件或者文件夹,包含子目录中的内容,也就是说我们想列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,在列出过程中出现的还是目录的话,还可以在此调用本功能。这就是函数自身调用自身,这种表现形式,或者编程手法称为递归。
递归:所谓递归就是方法调用自身,对于递归来说,一定有一个出口,让递归结束,只有这样才能保证不出现死循环。
我们使用递归要注意:
a) 限定条件:要有条件限制,否则会一直自调,无法停止
b) 要注意递归的次数,尽量避免内存溢出
下面我们演示下关于数学上十进制转换二进制以及求和,来使用递归方法做:
class RecursionDemo
{
publicstatic void main(String[] args)
{
//toBin(6);
System.out.println(getAdd(100));
}
/*
求把十进制转换二进制
*/
publicstatic void toBin(int num){
if(num>0)
{
toBin(num/2);//递归
System.out.print(num%2);
}
}
/*
求1-100的和
*/
publicstatic int getAdd(int num){
if(num==1)
return1;
returnnum+getAdd(num-1);//递归
}
}
那么我们就可以根据递归去解决去列出目录下所有的文件:
import java.io.*;
class ListFileDemo
{
publicstatic void main(String[] args)
{
Filedir=new File("D://JavaWork//");
listAllFile(dir,0);
}
/*
给文件夹下带层次
*/
public static String getLevel(int level){
StringBuildersb=new StringBuilder();
//文件夹下有多少文件就循环多少次
for(inti=0;i<level;i++){
sb.append(" ");
}
returnsb.toString();
}
/*
列出所有的文件和文件夹
*/
publicstatic void listAllFile(File dir,int level){
File[]f=dir.listFiles();
level++;
for(inti=0;i<f.length;i++){
if(f[i].isDirectory()){
listAllFile(f[i],level);
}
System.out.println(getLevel(level)+f[i]);
}
}
}
递归关联File应用:
第一个应用:在指定的文件夹下删除所有文件,即删除一个带内容的目录,删除的原理是在windows中,删除目录从里面往外删除的,既然是从里往外删,就需要用到递归。
import java.io.*;
class RemoveDir
{
publicstatic void main(String[] args)
{
File f=newFile("c://testdir//");
remove(f);
}
publicstatic void remove(File dir){
File[]f=dir.listFiles();
for(inti=0;i<f.length;i++){
if(f[i].isDirectory()){
remove(f[i]);
}else{
System.out.println(f[i]+":-文件-:"+f[i].delete());
}
System.out.println(dir+":文件夹:"+dir.delete());
}
}
}
第二个应用:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中,建立一个java文件列表文件。
我们首先对指定的目录进行递归。然后获取递归过程所有的java文件的路径,再将这些路径存储到集合中,最后将集合中的数据写入到一个文件中。
import java.io.*;
import java.util.*;
class CreateFileList
{
publicstatic void main(String[] args) throws IOException
{
ArrayList<File>list=new ArrayList<File>();
Filedir=new File("d://JavaWork");
listAdd(dir,list);
//System.out.println(list.size());
Filef=new File(dir,"javalist.txt");
writeTo(list,f.toString());
}
publicstatic void listAdd(File dir,List<File> list){
File[]file=dir.listFiles();
for(Filef:file){
if(f.isDirectory()){
listAdd(f,list);
}else{
if(f.getName().endsWith(".java")){
list.add(f);
}
}
}
}
publicstatic void writeTo(List<File> list,String name){
BufferedWriterbw=null;
FileWriterfw=null;
try
{
fw=newFileWriter(name);
bw=newBufferedWriter(fw);
for(Filef:list){
Stringpath=f.getAbsolutePath();//将获得绝对路径赋给path
bw.write(path);
bw.newLine();
bw.flush();
}
}
catch(IOException e)
{
System.out.println("写入失败");
}
finally
{
try
{
if(bw!=null)
bw.close();
}
catch(IOException ex)
{
System.out.println("关闭流失败");
}
}
}
}
Properties对象解析
Properties是Hashtable的子类,也就是说它具备map集合的特点,而且它里面存储的键值对都是都是字符串,它是集合中和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件,那么在加载的数据时,需要数据有固定格式:键=值
Properties有哪些常用方法呢?
a) Object setProperty():调用 Hashtable的方法 put,即存储
b) String getProperty():根据指定的键获取键所对应的值
c) Set<String> stringPropertyNames();Properties的遍历集合,用以遍历Properties的所有元素
d) void list(PrintStreamout):将属性列表输出到指定的输出流,例如System.out。
e) void load(InputStream inStream):将关联文件中键值对属性的流加载到Properties
f) void store(Writer w,Stringcomments):将修改后的属性值添加到一关联文件的写入流
我们现在将这些方法通过代码演示出来
import java.util.*;
import java.io.*;
class PropertiesDemo
{
publicstatic void main(String[] args) throws IOException
{
method_3();
}
publicstatic void method_3()throws IOException
{
InputStreamReader isr=newInputStreamReader(new FileInputStream("info.txt"));
Propertiesp=new Properties();
//将流中的数据加载进集合
p.load(isr);//将文件中的属性以键值对的形式加载到Properties属性里
FileWriterfw=new FileWriter("info.txt");
p.setProperty("张三","20");//设置张三的属性
p.list(System.out);//将文件中的属性打印到控制台上
p.store(fw,"haha");//此处最好不要写中文,将关联的输入流保存到文关联的件中
}
/*
这是Properties的load的形似的代码
*/
publicstatic void method_2()throws IOException
{
BufferedReaderbr=new BufferedReader(new FileReader("info.txt"));
Strings=null;
Propertiesp=new Properties();
while((s=br.readLine())!=null){
String[]str=s.split("=");
p.setProperty(str[0],str[1]);
sop(p);
}
br.close();
}
/*
这是Properties的一些基本存储方法
*/
publicstatic void method_1()
{
Propertiesp=new Properties();
p.setProperty("01","java01");
p.setProperty("02","java02");
System.out.println(p);
Stringvalue=p.getProperty("02");
System.out.println(value);
Set<String>name=p.stringPropertyNames();//使用遍历
for(Strings:name){
System.out.println(s+"::"+p.getProperty(s));
}
}
publicstatic void sop(Object obj){
System.out.println(obj);
}
}
Properties的应用:我们设置一个属性用于记录应用程序的运行次数,如果使用次数已到,那么给出注册提示:。我们可以使用一个计数器,该计数器不会随着程序的结束而归零,我们要让该计数器一直存在。程序即使结束,该技术区的值也存在,下次程序启动会先加载该计数器的值并加1后再重新存储起来。所以要建立一个配置文件,用与记录该软件的使用次数,该配置文件使用键值对的形式,这样便于阅读数据,并操作数据。我们综合使用map+io,即Properties,配置文件可以实现应用程序的数据的共享
import java.io.*;
import java.util.*;
class AppGoCoount
{
publicstatic void main(String[] args) throws IOException
{
if(!goCount()){
canGo();
}else{
sop("您好,你使用程序的次数超过了5次,想继续使用,请交钱");
System.exit(0);
}
}
publicstatic boolean goCount()throws IOException
{
Propertiespro=new Properties();
Filef=new File("count.properties");
if(!f.exists()){
f.createNewFile();
}
FileInputStreamfis=new FileInputStream(f);
pro.load(fis);
intcount=0;//计数器
Stringvalue=pro.getProperty("time");
if(value!=null){
count=Integer.parseInt(value);
if(count>=5){
returntrue;
}
}
count++;
pro.setProperty("time",String.valueOf(count));
FileOutputStreamfos=new FileOutputStream(f);
pro.store(fos,"count");
fos.close();
fis.close();
returnfalse;
}
publicstatic void canGo(){
sop("程序正常运行、、、、");
}
publicstatic void sop(Object obj){
System.out.println(obj);
}
}