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 ...
随机推荐
- [原创]java WEB学习笔记33:Session 案例 之 购物车
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Flask框架的学习与实战(二):实战小项目
昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统. blog系统很简单,只有一个页面,然而麻雀虽小五脏俱全.这里目的不是为了做项目而做项目,这篇文章本意是通过这次练习传达 ...
- vue-router原理分析
本文整理总结自: https://zhuanlan.zhihu.com/p/27588422 单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面, 实现这一点主要是两种方式: 1.Hash: ...
- 机器学习相关知识整理系列之一:决策树算法原理及剪枝(ID3,C4.5,CART)
决策树是一种基本的分类与回归方法.分类决策树是一种描述对实例进行分类的树形结构,决策树由结点和有向边组成.结点由两种类型,内部结点表示一个特征或属性,叶结点表示一个类. 1. 基础知识 熵 在信息学和 ...
- 剑指offer之 从上往下打印二叉树
import java.util.ArrayList; import java.util.LinkedList; /** public class TreeNode { int val = 0; Tr ...
- An Assembly Language
BUFFER OVERFLOW 3 An Assembly Language Introduction Basic of x86 Architecture Assembly Language Comp ...
- javascript作用域与闭包
Javasript作用域概要 在javascript中,作用域是执行代码的上下文,作用域有三种类型: 1) 全局作用域 2) 局部作用域(函数作用域) 3) eval作用域 var foo = ...
- Centos安装SZRZ方便文件传输
方便Centos服务器传输文件, 要用到szrz命令, 具体安装如下: # wget http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz# ta ...
- jQuery 对表单、表格的操作及更多应用-简略笔记
[jQuery 对表单.表格的操作及更多应用] jquery对表单及表格的操作是实际应用中相当广泛. 对于表单的操作,可以实现 (1)获取和失去焦点改变样式: (2)在多行文本框中可以实现网站评论框的 ...
- BEC listen and translation exercise 40
However, recently there's been more and more interest in the development of ostrich farming in other ...