Java IO File 文件管理 Java编程思想读书笔记
来源:互联网 发布:简述java垃圾回收机制 编辑:程序博客网 时间:2024/05/21 11:24
可以使用File管理磁盘上的文件。
File对象最简单的构造器接受一个完全的文件。如果没有提供路径名,则使用当前路径。
File f = new File("test.txt");
注意:考虑到可移植问题,可以使用File.separator得到当前 运行平台所使用的文件分隔符,在Windows环境中,它是反斜线(\),在UNIX环境中,它是斜线(/)。
如果File指定文件不存在。可以调用File类的createNewFile方法,createNewFile方法只有在具有指定的文件不存在时才会创建文件,并且返回boolean值说明文件是否创建成功。
可以调用File对象的exist方法查询指定的文件是否存在。
File对象既可以表示文件,也可以表示目录。可以使用isDirectory和isFile方法来了解一个文件对象表示的是文件还是目录。
让一个对象表示目录,只需在File构造器提供目录名:
File tempDir = new File(File.separator+"temp");
如果指定目录不存在,可以使用mkdir方法创建它:
tempDir .mkdir();
如果指定目录的父目录都不存在,可以使用mkdirs方法创建它:
tempDir .mkdirs();
如果一个文件对象表示的是目录,使用list()方法可以获得由这个目录的文件名构成的字符串数组。
如果我们想取得不同的目录列表,只需要再创建一个不同的File对象就可以了。
提示:在处理文件或目录名时,应该总是使用File对象而不是字符串。这样做的好处很多,如,File类的equals方法知道某些文件系统是不是大小写敏感的,而不是自己判断。
目录列表器
如果你想查看一个目录列表,可以调用不带参数的list()方法,便获得此File对象包含的全部列表。然而,如果想获得一个受限列表,如想得到所有扩展名为.java的文件,那么我们就是用到“目录过滤器”(FilenameFilter)。
下面是一个示例,注意,通过使用java.utils.Arrays.sort()和String.CASE_INSENSITIVE_ORDER,可以很容易地对结果进行排序(按字母排序)。
package ioStudy;import java.io.*;import java.util.Arrays;import java.util.regex.Pattern;//定义一个文件过滤器,根据正则表达式过滤文件class DirFilter implements FilenameFilter{private Pattern pattern;public DirFilter(String regex){pattern = Pattern.compile(regex);}public boolean accept(File dir, String name){return pattern.matcher(name).matches();}}public class DirList {public static void main(String[] args) {File path = new File("src/ioStudy");//当前java文件所在目录String[] list;list = path.list(new DirFilter("\\w+\\.java"));//查看所有的java文件Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);for(String dirItem : list) {System.out.println(dirItem);}}}
这里DirFilter类实现了FilenameFilter接口,注意FilenameFilter接口非常简单:
public interface FilenameFilter {boolean accept(File dir, String name);}
DirFilter存在的唯一原因就是实现accept方法。创建这个类目的在于把accept方法提供给list使用,使list可以回调accept,进而以决定哪些文件包含在列表中。因此,这种结构也常称为回调。更具体地说,这是一种策略模式的例子,因为list()实现了基本的功能,而且FilenameFilter的形式提供了过滤策略,以便完善list()在提供服务时所需的算法。因为list()接受FilenameFilter对象作为参数,这意味着我们可以传递实现了FilenameFilter接口的任何类的对象,用以选择(甚至在运行时)list()方法的行为方式。策略的目的就是提供了代码行为的灵活性。
accept()方法必须接受一个代表某个特定文件所在目录的File对象,以及包含了那个文件名的一个String。记住一点:list()方法会为此目录下的每个文件名调用accept(),来判断该文件是否包含在内;判断结果由accept()返回的布尔值表示。
accept()会使用一个正则表达式的matcher对象,来查看此正则表达式regex是否匹配这个文件的名字。通过使用accept(),list()方法会返回一个数组。
上面例子可以通过一个匿名内部类实现:
package ioStudy;import java.io.*;import java.io.FilenameFilter;import java.util.Arrays;import java.util.regex.Pattern;public class DirList3 {public static void main(String[] args) {File path = new File("src/ioStudy");//当前java文件所在目录String[] list;list = path.list(new FilenameFilter() {private Pattern pattern = Pattern.compile("\\w+\\.java");//查看所有的java文件public boolean accept(File dir, String name) {return pattern.matcher(name).matches();}});Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);for(String dirItem : list) {System.out.println(dirItem);}}}
此方法的一个优点就是将解决特定问题的代码隔离,聚拢于一点。而另一方面,这种方法不易阅读,因此要谨慎使用。
目录实用工具
程序设计中一项常见的任务就是在文件集上执行操作,这些文件要么在本地目录中,要么遍历于整个目录树中。如果有一种工具能够为你产生这个文件集,那么它会非常有用。下面的实用类可以通过使用local方法产生由本地目录中的文件构成的File对象数组,或者通过使用walk()方法产生给定目录下的由整个目录树中所有文件构成的List<File>。这些文件是基于你提供的正则表达式而被选中的:
import java.io.*; import java.util.*; import java.util.regex.Pattern; public class Directory { /** * @param dir 目录File * @param regex过滤正则表达式 * @return传递目的目录File和过滤正则表达式,返回目的目录下根据正则表达式过滤后的File数组 */ public static File[] local(File dir, final String regex) { return dir.listFiles(new FilenameFilter() { private Pattern pattern = Pattern.compile(regex); public boolean accept(File dir, String name) { return pattern.matcher(new File(name).getName()).matches(); } }); } /** * 传递目的目录字符串和过滤正则表达式,返回目的目录下根据正则表达式过滤后的File数组 */ public static File[] local(String path, final String regex) { return local(new File(path), regex); } //TreeInfo提供了文件迭代器和添加一个TreeInfo的方法 public static class TreeInfo implements Iterable<File> { public List<File> files = new ArrayList<File>(); public List<File> dirs = new ArrayList<File>(); public Iterator<File> iterator(){ return files.iterator(); } void addAll(TreeInfo other){ files.addAll(other.files); dirs.addAll(other.dirs); } public String toString() { return "dirs: " + PPrint.pformat(dirs) + "\n\nfiles: " + PPrint.pformat(files); } } /** * @param startDir目的目录File * @param regex过滤正则表达式 * @return 传递目的目录File和过滤正则表达式,返回目的目录下根据正则表达式过滤后构成的TreeInfo对象 */ private static TreeInfo recurseDirs(File startDir, String regex) { TreeInfo result = new TreeInfo(); for(File item : startDir.listFiles()) { if(item.isDirectory()) { result.dirs.add(item); } else if(item.getName().matches(regex)) { result.files.add(item); } } return result; } //提供接口 public static TreeInfo walk(String start,String regex) { return recurseDirs(new File(start), regex); } public static TreeInfo walk(File start, String regex) { return recurseDirs(start, regex); } public static TreeInfo walk(File start) { return recurseDirs(start, ".*");//everythig } public static TreeInfo walk(String start) { return recurseDirs(new File(start), ".*"); } public static void main(String[] args) { System.out.println(walk(".")); } }
local()方法使用了listFile()产生File数组。如果需要List而不是数组,可以使用Arrays.asList()对结果进行转换。
walk()方法将开始目录的名字转换为File对象,然后调用recurseDirs(),该方法将递归地遍历目录,并在每次递归中收集更多的信息。为了区分普通文件和目录,返回值实际上是一个对象“元组”--------- 一个List持有所有普通文件,另一个持有目录。这里,所有的域都被有意识地设置成public,因为TreeInfo的使命只是将对象收集起来----------如果你只是返回List,那么就不需要将其设置为private,因为你只是返回一个对象,不需要将它们设置为private。注意,TreeInfo实现了Iterable<File>,它将产生文件,使你拥有在文件列表上的“默认迭代”,而你可以通过声明“.dirs”来指定目录。
TreeInfo.toString()方法使用了一具“灵巧打印机”类,以便使输出更容易浏览。容器默认的toString()方法会在单行中打印容器中所有元素,对于大型集合来说,这会变得难以阅读,因此你可能希望使用可替换的格式化机制。下面是一个可以添加新行并缩排所有元素的工具:
import java.util.*;public class PPrint {public static String pformat(Collection<?> c) {if(c.size() == 0)return "[]";StringBuilder result = new StringBuilder("[");for(Object elem : c) {if(c.size() != 1)result.append("\n ");result.append(elem);}if(c.size() != 1)result.append("\n");result.append("]");return result.toString();}public static void pprint(Collection<?> c) {System.out.println(pformat(c));}public static void pprint(Object[] c) {System.out.println(pformat(Arrays.asList(c)));}}
pformat()方法可以从Collection中产生格式化的String,而pprint()方法使用pformat()来执行其任务。注意,没有任何元素和只有一个元素这两种特例进行了不同的处理。
我们更进一步,创建一个工具,它可以在目录中穿行,并且根据Strategy对象来处理这些目录中的文件(这是策略设计模式的另一个示例):
package ioStudy; import java.io.*; public class ProcessFiles { //策略接口 public interface Strategy { void process(File file); } private Strategy strategy; private String ext;//只处理以ext结尾的文件 public ProcessFiles(Strategy strategy, String ext){ this.strategy = strategy; this.ext = ext; } /** * 处理rootFile所在目录的所有文件 */ public void processDirectoryTree(File root) throws IOException { for(File file : Directory.walk(root.getAbsoluteFile(), ".*\\." + ext)){ strategy.process(file.getCanonicalFile()); } } /** * 将数组参数fileNames转化为File数组,并使用strategy处理所有的File */ public void start(String[] fileNames) { try { if(fileNames.length == 0) processDirectoryTree(new File(".")); else for(String fileName :fileNames) { File file = new File(fileName); if(file.isDirectory()) processDirectoryTree(file); else { if(!fileName.endsWith("." + ext)) fileName += "." + ext; strategy.process(new File(fileName).getCanonicalFile()); } } } catch(IOException e) { throw new RuntimeException(e); } } public static void main(String[] args) { new ProcessFiles(new ProcessFiles.Strategy() { public void process(File file) { System.out.println(file); } }, "java").start(new String[]{".", "src/ioStudy"}); } }
Strategy接口内嵌在ProcessFiles中,使得如果你希望实现它,就必须实现ProcessFiles.Strategy,它为读者提供了更多的上下文信息。ProcessFiles执行了查找具有特定扩展名(传递给构造器的ext参数)的文件所需的全部工作,并且当它找到匹配的文件时,将直接把文件传递给Strategy对象(也是传递给构造器的参数)。
如果你没有提供任何参数,那么ProcessFiles就假设你希望遍历当前目录下的所有目录,你也可以指定特定的文件,带不带扩展名都可以(如果必需的话,它会添加扩展名),或者指定一个或多个目录。
- Java IO File 文件管理 Java编程思想读书笔记
- Java IO 文件加锁 Java编程思想读书笔记
- Java IO 概念 Java编程思想读书笔记
- Java IO ZIP文档操作 Java编程思想读书笔记
- Java IO 典型用法 Java编程思想读书笔记
- Java IO 新I/O Java编程思想读书笔记
- 33.JAVA编程思想——JAVA IO File类
- Java编程思想读书笔记
- java编程思想读书笔记
- java 编程思想 读书笔记
- <<java编程思想>>读书笔记
- java编程思想读书笔记
- java编程思想读书笔记
- 《Java编程思想》读书笔记
- Java 编程思想 - 读书笔记
- JAVA编程思想读书笔记
- 《java编程思想》读书笔记
- java编程思想读书笔记
- crm快速开发之QueryExpression
- QTP实现简易定时器--完成定时脚本测试工作
- Apache + Tomcat集群配置
- cocos2dx sqlite3封装使用
- 在Excel中将数字转换为人民币大写风格的公式
- Java IO File 文件管理 Java编程思想读书笔记
- Eclipse快捷键大全(转载)
- js判断选择不同的样式文件
- UIApplication深入研究
- cocos2dx 3.0 使用cocostudio的UI动画(ActionManagerEx&&ActionObject)的bug修复
- zookeeper在hbase集群中的作用
- crm快速开发之EntityCollection
- ZOJ3326小技巧
- 周一感慨