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 ...
随机推荐
- rails跨域请求配置
gem 'rack-cors', '~> 0.3.1'application.rb config.middleware.insert_before 0, "Rack::Cors&quo ...
- CentOS 6.5 下安装配置GO 1.2.1
步骤1:保持联网状态,命令 # wget http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz 这里下载的是64位,wget这里默认下载到当前 ...
- PAT 天梯赛 L2-010. 排座位 【并查集】
题目链接 https://www.patest.cn/contests/gplt/L2-010 思路 因为 题意中 朋友的朋友 就是朋友 那么 朋友的关系 用 并查集 保存 但是 敌对关系 只有直接的 ...
- 【Flask】Sqlalchemy 常用数据类型
### SQLAlchemy常用数据类型:1. Integer:整形,映射到数据库中是int类型.2. Float:浮点类型,映射到数据库中是float类型.他占据的32位.3. Double:双精度 ...
- python正则-- re模块
匹配数字相关'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r" ...
- 系统安装记录 install OS
上个系统很乱,基本系统是lfs7.7,上面应用都是基于lfs7.9,基本系统是才接触lfs时搭建的,打包保存后一直没怎么使用过,到lfs7.10快出来的时候有段时间有空就拿出来跑了一下,安装了一些软件 ...
- LINQ 学习路程 -- 查询操作 Skip SkipWhile Take TakeWhile
Method Description Skip 跳过序列中指定数量元素,然后返回剩余序列 SkipWhile 只要满足条件,就跳过序列中的元素,然后返回剩余函数 Take 从序列的开头返回指定数量的连 ...
- 算法(Algorithms)第4版 练习 1.5.22
package com.qiusongde; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdStats; ...
- 大话设计模式--享元模式 Flyweight -- C++实现实例
1. 享元模式: 运用共享技术有效地支持大量细粒度的对象. 享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生成大量颗粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本都是相同的 ...
- for循环中删除map中的元素,valgrind检测提示error:Invalid read of size 8
#include <iostream> #include <map> using namespace std; class A { public: typedef std::m ...