IO系列之File
1 File类
1.1 目录列表器
在这里我主要是参考Think in Java的内容从而做的一些总结以及扩展。Java中的IO流的设计应该说是Java中最经典的,最学院式的设计,包括它的整体架构设计以及代码的构造。
现在让我们开始进行文件过滤吧。说到这里,说一下这个File类,从类名上看,它表示文件的意思,但是这个意思却不是准确的表达它的含义,FilePath应该来说更加的符合,它表示的就是文件的路径。好了,让我们看看当前的文件目录吧。
这个就是当前文件所在的目录。
好了,让我先列出所有的文件列表吧。
package cn.czg.io; import java.io.File; /**
* 目录列表器
*/
public class DirListDemo {
public static void main(String[] args) {
/** 文件表示当前目录*/
File filePath=new File(".");
/** 当前目录的文件名称组成一个String[] 数组*/
String[] list = filePath.list();
for (String listDir:list) {
System.out.println(listDir);
/**
* .idea
* pom.xml
* spring40parent.iml
* src
* target
* 测试.java
*/
}
}
}
上面的输出结果和文件的目录是一致的。不带参数的list()方法的功能就是返回一个该目录下的文件名的String数组。
public String[] list() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return null;
}
return fs.list(this);
}
security是一个安全管理器对象,第一个判断是判断安全管理器是否为空,这个目的是为了分配文件的操作权限,比如读写的权限,第二个判断则是判断文件的路径时候合理或者存在。关于安全管理器我希望在有时间的时候作为单独的一个系列来研究下它的源码。在这里我希望不要深究。
1.2 文件过滤器
在大多的时候我们还是希望得到我们想要的文件,比如后缀是.java结尾的文件,在jdk中,存在着专门的一个接口,就是FilenameFilter.它表示的就是文件过滤器。
@FunctionalInterface
public interface FilenameFilter { boolean accept(File dir, String name);
}
当且仅当该文件名称包含在文件列表中,则返回true,其他的返回false.好了,让我们实践一把吧。
在操作之前,我们来看看file.list()的api 
大家可以清楚的看到,下面的list()方法带有参数,参数是一个filter,即文件过滤器。
请看如下的代码:
/**
* 目录列表器
*/
public class DirListDemo {
public static void main(String[] args) {
/** 文件表示当前目录*/
File filePath=new File(".");
/** 当前目录的文件名称组成一个String[] 数组*/
//String[] list = filePath.list();
// list方法包含了所有的文件的名称
// 如果要调用含有参数的list方法,此时就需要一个FilenameFilter的实现类,并且实现正则匹配
MyFilenameFilter filter=new MyFilenameFilter(".java");
String[] list = filePath.list(filter);
for (String dirList:list) {
System.out.println(dirList);
}
}
}
class MyFilenameFilter implements FilenameFilter{
private String regex;
public MyFilenameFilter(String regex) {
this.regex=regex;
} @Override
public boolean accept(File dir, String name) {
return name.endsWith(regex);
}
}
打印结果毫无疑问的将后缀为Java的文件帅选出来,好了,接着我们可以对刚才的代码进行优化,让它看起来比较完美。
优化一 匿名内部类:
public class DirListDemo3 {
public static void main(String[] args) {
/** 文件表示当前目录*/
File filePath=new File(".");
String[] list = filePath.list(filter(".java"));
for (String dirList:list) {
System.out.println(dirList);
}
}
public static FilenameFilter filter(String regex){
return new FilenameFilter() {
private String regexs=regex;
@Override
public boolean accept(File dir, String name) {
return name.endsWith(regexs);
}
};
}
}
大家可以看到,上述的FilenameFilte作为方法的返回值进行了传递,此时FilenameFilte掺杂在DirListDemo3中,所以我们直接将FilenameFilte作为方法的参数直接传递也是可以的,这样也是降低了耦合:
优化二:FilenameFilte作为参数传递:
public class DirListDemo {
public static void main(String[] args) {
/** 文件表示当前目录*/
File filePath=new File(".");
String regex=".java";
String[] list = filePath.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(regex);
}
});
for (String dirList:list) {
System.out.println(dirList);
}
}
}
1.3 目录实用工具
现在我的需求就是列出当前文件下的所有的文件或者文件夹
看到这里我们很容易想到递归的操作方式,确实如此,本例也是使用的递归的算法来完成
public class Directory2 {
public static void main(String[] args) {
File file=new File(".");
list(file);
}
public static void list(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
if(files!=null){
for (int i=0;i<files.length;i++){
// 此时files[i]表示的是一个文件或者文件目录
//采用递归算法,直接调用list()方法,将files[i]作为参数进行传递
list(files[i]);
}
}
}
System.out.println(file);
}
}
在Think in java中,封装了一个工具类来完成相同的功能。但是功能要比我上述的写的完全要多。我做了相应的修改,使得代码变得可读性较好
package cn.czg.io; import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Directory {
/**
* 该方法返回一个File[]数组,和我们之前的目录列表器是相同的,
* 通过特定的形式返回特定的文件
* @param dir
* @param regex
* @return
*/
public static File[] local(File dir,final String regex){
return dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(regex);
}
});
} /**
* 该方法和上述的local()方法是方法的重载,只不过此时传递的参数均为字符串,
* 第一个参数为文件路径的目录的字符串表达形式,第二个参数相同
* 最后调用第一个local()方法
* @param path
* @param regex
* @return
*/
public static File[] local(String path,final String regex){
return local(new File("path"),regex);
} /**
* 定义一个静态内部类TreeInfo,表示的是文件目录树,实现Iterable,实现此接口的类就可以
* 成为forech的目标
*/
public static class TreeInfo implements Iterable<File>{
/**
* 定义两个list集合,分别是files(文件list)以及dirs(目录list)
*/
public List<File> files=new ArrayList<>();
public List<File> dirs=new ArrayList<>(); /**
* 覆盖iterator()方法,返回一个File的比较器
* @return
*/
@Override
public Iterator<File> iterator() {
return files.iterator();
}
void addAll(TreeInfo other){
/**
* 将集合files和集合dirs全部添加到对应的list当中
*/ files.addAll(other.files);
dirs.addAll(other.dirs);
} @Override
public String toString() {
return "TreeInfo{" +
"files=" + files +
", dirs=" + dirs +
'}';
}
} /**
* 在这里分析下,TreeInfo表示的就是目录树对象,有两个字段
* files和dirs,这两个集合分别存储文件和目录,而recurseDirs()方法返回的就是TreeInfo对象
* 这个对象保存了文件和目录,walk()的作用就是执行。
* @param start
* @param regex
* @return
*/
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,".*");
}
public static TreeInfo walk(String start){
return recurseDirs(new File(start),".*");
} /**
*
* @param startDirs
* @param regex
* @return
*/
static TreeInfo recurseDirs(File startDirs, String regex) {
TreeInfo result=new TreeInfo();
for (File item:startDirs.listFiles()) {
if(item.isDirectory()){
result.dirs.add(item);
/**
* 递归方法的出口,如果该文件下存在子文件或者子文件夹,
* 继续调用recurseDirs()方法,返回的TreeInfo目录树对象添加到
* list集合当中
*/
result.addAll(recurseDirs(item,regex));
}else {
/**
* 否则,直接帅选
*/
if(item.getName().endsWith(regex))
result.files.add(item); }
}
return result;
} public static void main(String[] args) {
File[] local = local(new File("."), ".java");
for (File fs:local) {
System.out.println(fs);
}
}
}
IO系列之File的更多相关文章
- java io系列08之 File总结
本文对File的API和常用方法进行介绍. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_08.html File 介绍 File 是“文件”和“目 ...
- java io系列16之 PrintStream(打印输出流)详解
本章介绍PrintStream以及 它与DataOutputStream的区别.我们先对PrintStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解. 转载请注明出处:htt ...
- java io系列01之 "目录"
java io 系列目录如下: 01. java io系列01之 "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...
- java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例
本章介绍DataOutputStream.我们先对DataOutputStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解. 转载请注明出处:http://www.cnblog ...
- Java IO系列之一:IO
1. 概述 Java IO一般包含两个部分: 1.java.io包中堵塞型IO: 2.java.nio包中的非堵塞型IO,通常称为New IO. java.io包下,分为四大块近80个类: 1.基于字 ...
- io系列之字节流
java中io流系统庞大,知识点众多,作为小白通过五天的视频书籍学习后,总结了io系列的随笔,以便将来复习查看. 本篇为此系列随笔的第一篇:io系列之字节流. 一.字节流的File读写操作. Inpu ...
- io系列之字符流
java中io流系统庞大,知识点众多,作为小白通过五天的视频书籍学习后,总结了io系列的随笔,以便将来复习查看. 本篇为此系列随笔的第一篇:io系列之字符流. IO流 :对数据的传输流向进行操作,ja ...
- java io系列07之 FileInputStream和FileOutputStream
本章介绍FileInputStream 和 FileOutputStream 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_07.html File ...
- java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
本章内容包括3个部分:BufferedInputStream介绍,BufferedInputStream源码,以及BufferedInputStream使用示例. 转载请注明出处:http://www ...
随机推荐
- Spring声明式事务管理与配置介绍
转至:http://java.9sssd.com/javafw/art/1215 [摘要]本文介绍Spring声明式事务管理与配置,包括Spring声明式事务配置的五种方式.事务的传播属性(Propa ...
- DB2常见错误
+098 01568 动态SQL语句用分号结束+100 02000 没有找到满足SQL语句的行+110 01561 用DATA CAPTURE定义的表的更新操作不能发送到原来的子系统+111 0159 ...
- 利用Tkinter做的自动生成JSONSchema的小工具
前面讲到可以使用JSONSchema做json数据校验, 但是每个接口数据都手动写jsonschema太痛苦了, 就写了个小脚本,可以直接复制接口文档的mock数据然后生成一个简单的jsonschem ...
- ubantu卸载软件
参考:https://blog.csdn.net/luckydog612/article/details/80877179 https://blog.csdn.net/get_set/article/ ...
- Luogu P1377 [TJOI2011]树的序:离线nlogn建二叉搜索树
题目链接:https://www.luogu.org/problemnew/show/P1377 题意: 有一棵n个节点的二叉搜索树. 给出它的插入序列,是一个1到n的排列. 问你使得树的形态相同的字 ...
- JQuery 常用代码
1.选择器 1.根据标签名: $('p') 选择文档中的所有段落 2. 根据ID: $("#some-id") 3.类: $('.some-class') $('.t ...
- hdu 1864 最大报销额(01背包)
最大报销额 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 使用jquery执行ajax
$.ajax():返回其创建的XMLHttpRequest对象 回调函数:如果要处理$.ajax()得到的数据,则应该使用回调函数!beforeSend:在发送请求之后调用,需要一个XMLHttpRe ...
- Windows PCM音频捕获与播放实现
在WINDOWS下,音频函数有多种类型,如MCI.多媒体OLE控制.高级音频等,使用方法都比较简单.但如果想编写一个功能较强大的音频处理程序,那就必须使用低级音频函数和多媒体文件I/O来控制音频设备的 ...
- 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树
!前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...