一、概述:File类是有文件或文件件封装而来的对象,可以操作其属性信息,这个类的出现弥补了流的不足,流只能操作数据
1、特点:
1)用来将文件或文件夹封装成对象
2)方便于对文件与文件夹的属性信息进行操作
3)File对象可以作为多数传递给流的构造函数
2、File类常见方法:
实例:
public class FileDemo { public static void main(String[] args) { // consMethod(); // method(); // listFilesDemo(); // File dir = new File("E:\\develop\\eclipse space\\android workspace\\Test_java\\src"); // showDir(dir); // method_1(); // method_2(100); } /** * 构造方法演示 */ public static void consMethod(){ //创建file对象,可以将已有的和未出现的文件或目录封装成对象 File f1 = new File("C:" + File.separator + "a.txt");//File.separator跨平台的目录分隔符 File f2 = new File("c:\\abc","b.txt");//C:\\abc\\b.txt一样,但是两个参数更灵活,可以目录不变,文件变 File d = new File("c:\\abc"); File f3 = new File(d,"c.txt"); //这俩个和f2一样,不过f2目录是字符串对象,只能操作字符串方法 System.out.println("f1: " + f1); System.out.println("f2: " + f2); System.out.println("f3: " + f3); } /** * 演示File类的一些常用方法 */ public static void method_1(){ File f = new File("file.txt"); //exists()方法查看文件或目录是否存在 System.out.println("exists:" + f.exists()); //测试应用程序是否可以执行此抽象路径名表示的文件。 System.out.println("canExecute:" + f.canExecute()); //创建文件夹 // File dir = new File("C:\\ab\\c\\v\\g"); // System.out.println("mkdir:" + dir.mkdir());//最多只能创建两级目录,已经存在或失败返回false // System.out.println("mkdirs:" + dir.mkdirs());//创建多级目录 File f1 = new File("c:\\ab\\d.java"); try { f1.createNewFile();//createNewFile创建新文件 } catch (IOException e) { e.printStackTrace(); } //判断文件对象是否是文件或目录时,必须要先判断文件对象封装内容是否存在 //通过exists方法 System.out.println("isDir:" + f1.isDirectory());//是否是目录 System.out.println("isFile:" + f1.isFile());//是否是文件 //获取路径 System.out.println("path: " + f1.getPath()); System.out.println("abspath: " + f1.getAbsolutePath()); System.out.println("parent: " + f1.getParent()); //该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。 //如果相对路径中有上一层目录那么该目录就是返回结果。 //重命名,其实就是远文件再创建一个新文件,再把内容写入文件 (复制+重命名) File f2 = new File("c:\\ab\\d.java"); File f3 = new File("d:\\d.java"); System.out.println("rename:" + f2.renameTo(f3)); }
File[] files = File.listRoots();
for(File file : files){ //输出的是自己电脑上的各个盘的盘名 System.out.println(file);
list方法(重点)
* 获取当前目录下的文件以及文件夹的名称,包含隐藏文件。
* 调用list方法的File对象中封装的必须是目录。
* 否则会发生NullPointerException
* 如果访问的系统级目录也会发生空指针异常。
*
* 如果目录存在但是没有内容,会返回一个数组,但是长度为0.
public static void listDemo() { File file = new File("c:\\"); // a.txt错误 String[] names = file.list(); System.out.println(names.length); for (String name : names) { System.out.println(name); } }
如果是是获取.java文件,需要过滤器
public class FilterBytxt implements FilenameFilter(文件名过滤) { //过滤器,过滤txt文件 public boolean accept(File dir, String name) {// System.out.println(dir+"---"+name); return name.endsWith(".txt"); } } //可是每次过滤txt,过滤Java又得改。这个方法可以这样写 public class SuffixFilter implements FilenameFilter { private String suffix ; public SuffixFilter(String suffix) { 传个什么过滤什么 super(); this.suffix = suffix; } @Override public boolean accept(File dir, String name) { return name.endsWith(suffix); } } public static void listDemo_2() { File dir = new File("c:\\"); String[] names = dir.list(new FilterBytxt );//(new SuffixFilter(".txt")); for(String name : names){ System.out.println(name); } }
listFiles()方法返回File对象 ,还有文件过滤和文件名过滤(常用),拿了对象拿名字和大小很简单 list是过滤文件名,不能过滤文件
String[] names = file.list(); System.out.println(names.length); for(String name : names){ System.out.println(name);
public class FilterByHidden implements FileFilter(文件过滤) { //过滤器,过滤隐藏文件,用 listFiles @Override public boolean accept(File pathname) { return !pathname.isHidden(); //不要隐藏为真 } } public static void listDemo_3() { File dir = new File("c:\\"); File[] files = dir.listFiles(new FilterByHidden()); for(File file : files){ System.out.println(file); } }
需求:对指定目录进行所有内容的列出(包含子目录中的内容)
也可以理解为 深度遍历。不要遍历C、d、e盘,太复杂,会发生空指针异常
用listfiles
public class FileTest {
public static void main(String[] args) {
File dir = new File("e:\\demodir");
listAll(dir,0);
}
public static void listAll(File dir,int level) {//计数器level,增加一个目录就记录缩进一次,多个方法要记数,所以要传进去,不要定义
每个目录都要传进这个参数里边去listAll(File dir,int level),来打印目录
System.out.println(getSpace(level)+dir.getName()); //方法里调用方法,递归
//获取指定目录下当前的所有文件夹或者文件对象
level++;
//只遍历用增强,操作角标用普通for
File[] files = dir.listFiles();
for(int x=0; x<files.length; x++){
if(files[x].isDirectory()){
listAll(files[x],level);
如果是目录,继续列,然后循环,再判断,再列,可是不知道有几级目录,可以
listAll(File dir,int level)这个方法是列目录中的内容,如果files[x]是个目录的话,可以将
files[x]传进 listAll就可以了,就可以列出这个目录的内容
}
else
System.out.println(getSpace(level)+files[x].getName()名字,也可以是路径);这个打印的都是文件
}
}
private static String getSpace(int level) {//缩进
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int x=0; x<level; x++){
sb.insert(0,"| ");//从0参入
}
return sb.toString();
}
}
public static void method(){ File dir = new File("C:\\"); String[] names = dir.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { // System.out.println("dir:" + dir + ".....name::" + name); return name.endsWith(".txt"); } }); System.out.println("list.len:::" + names.length); for(String name : names){ System.out.println(name); } }
递归:对于每次循环都是用同一个功能的函数,即函数自身调用自身,这种表现形式或手法,称为递归。
注意:
1、限定条件,是作为结束循环用的,否则是死循环
public static void show(){
method();
}
public static void method(){
show();
}
2、注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法那个方法,所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。
实例一:求和和求二进制
* 递归方法演示 public static int method_2(int num){ // //求和 // if(num == 1){ // return 1; // } // return num + method_2(num - 1); //求二进制 StringBuilder sb = new StringBuilder(); if(num > 0){ method_2(num/2); int i = num%2; sb.append(i); } System.out.println(sb.toString()); return -1; }
实例二:显示所有目录下的文件,也就是说只要是目录就被循环
思路:既然要显示所有文件,就是要循环每一个文件夹,找出所有文件,这里操作文件夹的动作都是一样的,所有需要用到递归:
* 显示所有目录下的文件,也就是说只要是目录就被循环 public static void showDir(File dir){ System.out.println(dir); File[] files = dir.listFiles(); for(File f : files){ if(f.isDirectory()){ showDir(f); }else{ System.out.println(f); } } }
实例三:删除一个带内容的目录。
*
* 原理:必须从最里面往外删。
* 需要进行深度遍历。
public class RemoveDirTest { public static void main(String[] args) { File dir = new File("e:\\demodir"); // dir.delete(); removeDir(dir); } public static void removeDir(File dir) { File[] files = dir.listFiles(); for (File file : files) { if (file.isDirectory()) { removeDir(file); } else { System.out.println(file + ":" + file.delete()); } } System.out.println(dir + ":" + dir.delete()); }}
综合练习---文件清单列表
* 获取指定目录下,指定扩展名的文件(包含子目录中的)
* 这些文件的绝对路径写入到一个文本文件中。
*
* 简单说,就是建立一个指定扩展名的文件的列表。
*
* 思路:
* 1,必须进行深度遍历。
* 2,要在遍历的过程中进行过滤。将符合条件的内容都存储到容器中。多了存储起来,想怎么操作都行
* 3,对容器中的内容进行遍历并将绝对路径写入到文件中。
public class Test { public static void main(String[] args) throws IOException { File dir = new File("e:\\java0331"); FilenameFilter filter = new FilenameFilter() {// 过滤器,匿名内部类 public boolean accept(File dir, String name) { return name.endsWith(".java"); } }; List<File> list = new ArrayList<File>(); getFiles(dir, filter, list); File destFile = new File(dir, "javalist.txt");// 目的文件,当前文件 write2File(list, destFile); } /** * 对指定目录中的内容进行深度遍历,并按照指定过滤器,进行过滤, 将过滤后的内容存储到指定容器List中。 File * dir,FilenameFilter filter,List<File> list一个目录,文件名过滤,存储的容器 */ public static void getFiles(File dir, FilenameFilter filter, List<File> list) { File[] files = dir.listFiles(); // 深度遍历 for (File file : files) { if (file.isDirectory()) { // 递归 getFiles(file, filter, list); } else { // 对遍历到的文件进行过滤器的过滤。将符合条件File对象,存储到List集合中。 if (filter.accept(dir, file.getName())) { list.add(file); } } } } // 将集合写到文件去 public static void write2File(List<File> list, File destFile) throws IOException { BufferedWriter bufw = null; try { bufw = new BufferedWriter(new FileWriter(destFile)); for (File file : list) { bufw.write(file.getAbsolutePath()); bufw.newLine(); bufw.flush(); } } /* * catch(IOException e){//可以写可以不写 * * throw new RuntimeException("写入失败"); } */ finally { if (bufw != null) try { bufw.close(); } catch (IOException e) { throw new RuntimeException("关闭失败"); } } }}
实例四:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
思路: 1、对指定目录进行递归 2、获取递归过程中所有的java文件 3、把路径存放在集合中 4、把集合中的数据写入文件
* 将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。 * * 思路: * 1、对指定目录进行递归 * 2、获取递归过程中所有的java文件 * 3、把路径存放在集合中 * 4、把集合中的数据写入文件 */ public class JavaFileList { public static void main(String[] args) { // 指定查找路径 File dir = new File( "E:\\develop\\eclipse space\\android workspace\\Test_java"); // 定义集合用于存储取到的java路径 List<File> list = new ArrayList<File>(); fileToList(dir, list);// 调用查找文件方法 // System.out.println(list.size()); // 指定写入文件路径 File file = new File("c:\\", "javalist.txt"); writeToFile(list, file.toString());// 调用写入文件的方法 } /* * 获取指定目录下的java文件 */ public static void fileToList(File dir, List<File> list) { File[] files = dir.listFiles();// 返回该目录下的文件对象 for (File f : files) { if (f.isDirectory()) { fileToList(f, list); } else { if (f.getName().endsWith(".java")) ;// 找出java文件 list.add(f); } } } /* * 将数据写入文件中 */ public static void writeToFile(List<File> list, String filepath) { BufferedWriter bfw = null; try { bfw = new BufferedWriter(new FileWriter(filepath)); for (File f : list) { String path = f.getAbsolutePath();// 获取文件绝对路径 bfw.write(path); bfw.newLine(); bfw.flush(); } } catch (IOException e) { e.printStackTrace(); } finally { if (bfw != null) { try { bfw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
一、概述:
1、Properties是Hashtable的子类,也就是map集合的子类,所有具备Map集合的特点,而且它里面还有存储的键值对,都是字符串,无泛型定义。是集合中和IO技术相结合的集合容器。
2、特点:
1)可用于键值对形式的配置文件
2)在加载时,需要数据有固定的格式,常用的是:键=值
二、特有方法:
1、设置和获取元素:
Object setProperty(String key,String value)调用Hashtable
的方法put,将键和值存入到properties对象中
String getProperty(String key)用指定的键在此属性列表中搜索属性
Set<String> stringPropertyName()返回此属性列表中的键集
void load(InputStream ism)从输入流中读取属性列表(键和元素对)。
void load(Reader reader)按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
实例:
public class ProPertiesDemo { public static void main(String[] args) { getAndSet(); // method(); loadDemo(); } /* * 设置和获取元素。 */ public static void getAndSet(){ Properties pro = new Properties(); pro.setProperty("zhangsan", "20"); pro.setProperty("lisi", "30"); System.out.println(pro); //{zhangsan=20, lisi=12} String value = pro.getProperty("lisi"); System.out.println("getProperty: " + value); //获取 pro.setProperty("lisi", "90"); //修改 Set<String> names = pro.stringPropertyNames(); //取出所有键和值 for(String name : names){ //String value = pro.getProperty(name ); System.out.println(name + "::" + pro.getProperty(name)); //System.out.println(name + "::" + value); } }
list方法
public static void methodDemo_2(){ Properties prop = new Properties(); //存储元素。 prop.setProperty("zhangsan","30"); prop.setProperty("lisi","31"); ///prop = System.getProperties(); 打印出所有配置信息 prop.list(System.out); //键和值全部打印出,但是不能操作,zhangsan=20,lisi=12 } //store方法,将集合中数据存储到文件中 public static void methodDemo_3() throws IOException { Properties prop = new Properties(); //存储元素。 prop.setProperty("zhangsan","30"); prop.setProperty("lisi","31"); //想要将这些集合中的字符串键值信息持久化存储到文件中。 //需要关联输出流。 FileOutputStream fos = new FileOutputStream("info.txt"); //将集合中数据存储到文件中,使用store方法。 prop.store(fos, "info"); //"info"键值信息,不要写中文,Java中配置信息文件的后缀名是 properties,window是ini fos.close(); }
将集合中数据存储到文件中,使用store方法
将文件中数据存储到集合中,使用load方法
注意;必须要保证该文件中的数据是键值对
需要使用到读取流
public static void methodDemo_4() throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream("info.txt"); //使用load方法。 prop.load(fis); prop.list(System.out); //调试,验证}
模拟load方法
练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。
个性化设置原理都是这样,设置修改完了关了再打开,还是修改后的,因为配置文件(ini后缀)改变了
public class PropertiesTest { public static void main(String[] args) throws IOException { getAppCount(); } public static void getAppCount() throws IOException { // 将配置文件封装成File对象。 File confile = new File("count.properties"); // 新建的配置 if (!confile.exists()) { confile.createNewFile(); } FileInputStream fis = new FileInputStream(confile); // confile是个文件 Properties prop = new Properties(); prop.load(fis); // 将文件的数据存储在集合中 // 从集合中通过键获取次数(time是键)。 String value = prop.getProperty("time"); // 定义计数器。记录获取到的次数。不能直接time++,因为第一次运行时没有配置信息文件,新建了一个,但是没有数据,拿不到 // 值,返回null int count = 0; if (value != null) { count = Integer.parseInt(value);// 次数是字符串,需要转换 if (count >= 5) { // System.out.println("使用次数已到,请注册,给钱!"); // return; throw new RuntimeException("使用次数已到,请注册,给钱!"); } } count++; // 将改变后的次数重新存储到集合中。 prop.setProperty("time", count + ""); // 名字:次数(转成字符串) FileOutputStream fos = new FileOutputStream(confile); prop.store(fos, ""); fos.close(); fis.close(); }}