最近看了一道面试题,学习一下FileFilter和FileNameFilter
编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad
package com.darren.test.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
public class FileFilterTest {
public static void main(String[] args) {
File srcDir = new File("D:/java");
if (!srcDir.exists() || !srcDir.isDirectory()) {
srcDir.mkdir();
}
/**
* 长见识了,之前不知道还有FIleFilter和FileNameFilter来过滤文件,一般遇到这种问题都是自己在读文件时去判断文件的后缀
*/
/**
* 这也就是Java的策略模式,只要实现不同的filter接口的不同逻辑,就可以得到不同的结果,只不过, 我这里是匿名实现的FileFilter和FileNameFilter接口
*/
// FileFilter fileFilter = new FileFilter() {
//
// @Override
// /**
// *
// * @param pathname 当前读到的文件
// * @return
// */
// public boolean accept(File pathname) {
// return pathname.getName().endsWith(".java");
// }
// };
//
// File[] files = srcDir.listFiles(fileFilter);
FilenameFilter fileNameFilter = new FilenameFilter() {
@Override
/**
* @param dir - 被找到的文件所在的目录
* @param name - 文件的名称
* @return
*/
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
};
File[] files = srcDir.listFiles(fileNameFilter);
File targetDir = new File("D:/jad");
if (!targetDir.exists() || !targetDir.isDirectory()) {
targetDir.mkdir();
}
for (File file : files) {
try {
FileInputStream fin = new FileInputStream(file);
String targetFileName = file.getName().replaceAll("\\.java$", ".jad");
File targetFile = new File(targetDir, targetFileName);
FileOutputStream fout = new FileOutputStream(targetFile);
copy(fin, fout);
try {
fin.close();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
private static void copy(FileInputStream fin, FileOutputStream fout) {
int length = 0;
byte[] buff = new byte[1024];
try {
while ((length = fin.read(buff)) != -1) {
fout.write(buff, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1. 得到某个目录下的所有的java文件集合 1.1 得到目录
File srcDir = new File("D:/java");
1.2 得到目录下的所有java文件:
File[] files = srcDir.listFiles(fileFilter);
1.3 只想得到.java的文件:
FileFilter fileFilter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java");
}
};
2.将每个文件复制到另外一个目录,并改扩展名
2.1 得到目标目录,如果目标目录不存在,则创建之
2.2 根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
2.3 根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。
2.4 将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。
分析listFiles方法内部的策略模式实现原理
public File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();
}