Java I/O 系统-File类(一)-文件及其内容过滤

时间:2023-02-22 19:28:49

摘要: 本系列都是梳理《java编程思想》Java I/O章节的知识点,例子来源于书上的练习题。目标是对I/O这一章节所有知识点都梳理一遍,实现所有的练习题。

  • 目录列表检查器

练习一:假设我们想查看受限的一个目录列表,并检查尾随的参数是否存在那个文件中,以检查结果来决定是否接受那个文件。

package eighteenIO;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.regex.Pattern;

/**
* 原题是将修改一个例题,但由于例题中又用到私有工具类所以我采取重写所有方法
* 例子没有进行完善的封装,大体意图和原习题一样
* 程序的意图是:
* 1:查找某个文件夹(本例题采用程序本地目录)
* 2:查找某个文件是否在文件夹中(本例题采用建立一个test.txt文件)
* 3:查找该文件是否包含某个某个字符串
* 4:支持多个字符串查找
* 需要用到FilenameFileter接口,和File.list()方法,list()可以回调accept();
*
*/



public class TestExcOne {

public static void main(String[] args) {
try {
//查找的目的文件,及匹配的字符串数组
String[] teString = { "test.txt", "hello","hellos" };
File path = new File(".");//路径程序所在的目录
String[] list;
if (teString.length == 0)
list = path.list();
else
list = path.list(new DirFilter(teString));
Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
for (String dirItem : list) {
//由于没有用单元测试,这里匹配的字符串数组有无法匹配的,所以没打印,程序没问题
System.out.println(dirItem);
}
} catch (Exception e) {
e.printStackTrace();

}
}
}
//实现FilenameFilter ,重写accept方法
class DirFilter implements FilenameFilter {
private Pattern pattern;
String[] regex;

public DirFilter(String[] regex) {
this.regex=regex;

pattern = Pattern.compile(regex[0]);
}

public boolean accept(File dir, String name) {
boolean fileFound= false;
boolean stringFound=false;
boolean result= false;
String text=null;

fileFound= pattern.matcher(name).matches();
//判断文件是否存在
if (fileFound) {
TextFile tFile= new TextFile( new File(dir,regex[0]));
text =tFile.getAllSource();
System.out.println(regex[0]+"file content is "+text);
for (int i = 1; i < regex.length; i++) {
stringFound= text.contains(regex[i]);
//判断字符串是否存在
if (!stringFound) {
System.out.println(regex[i]+"not found");
}else {

System.out.println(regex[i] +"has been found");
}

}
}

//返回判断结果
if (fileFound&&stringFound) {
result=true;
}
return result;

}
}
//这是一个工具类:读取文件,以字符串的形式返回文件内容
class TextFile {
private File file;

public TextFile(File file) {
this.file=file;
}

public String getAllSource() {
StringBuilder sBuilder = new StringBuilder();
try {

BufferedReader reader = new BufferedReader(new FileReader(file));

String line = null;
while (!((line = reader.readLine()) == null)) {

sBuilder.append(line);
}
reader.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return sBuilder.toString();
}

}

输出式test.txtfile content is hello world
hello has been found
hellos not found

练习二:创建一个叫做SortedDridList的类,它具有一个可以接受文件路径的信息,并能构建改路径所有的排列目录列表的下所有文件排序目录列表的构造器。向这个类添加的两个重载的list()方法:一个产生整个列表,另一个产生与其参数(一个正则表达式)相匹配的列选表的子集。

package eighteenIO;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;

class SortedDirList {
String path;
File file;
//无参函数,调用程序本地目录
public SortedDirList() {
file = new File(".");
}
//传递目录path
public SortedDirList(String path) {
this.path = path;
file = new File(path);
if (!file.exists()) {
System.out.println("this is not a file");
} else if (!file.isDirectory()) {
System.out.println("this is not a directory");
}
}
//无参列表
public void list() {
file.list();
System.out.println(Arrays.toString(file.list()));
}
//正则列表
public void list(String regex) {

file.list(new DirFilter1(regex));
System.out.println(Arrays.toString(file.list(new DirFilter1(regex))));
}

}

class DirFilter1 implements FilenameFilter {
private Pattern pattern;

public DirFilter1(String regex) {

pattern = Pattern.compile(regex);
}

public boolean accept(File dir, String name) {

return pattern.matcher(name).matches();

}
}

public class TestSortedDirList {

public static void main(String[] args) {
SortedDirList sDirList = new SortedDirList();
SortedDirList sDirList1 = new SortedDirList();
sDirList.list();
System.out.println("-------------------");
sDirList1.list("test.txt");

}
}

输出式样:

[.classpath, .project, .settings, bin, src, test.txt]

[test.txt]

假设我们想查看受限的一个目录列表,对所选中的文件进行计算文件尺寸的总和

package eighteenIO;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;

public class TestExcThree {

public static void main(String[] args) {
try {
String teString = "test.txt";
File path = new File(".");
String[] list;
list = path.list(new DirFilter2(teString));
Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
long bytes = 0;
for (String dirItem : list) {
File fileList = new File(path, dirItem);
bytes += fileList.length();
}
System.out.println(Arrays.toString(list) + " has " + bytes + " byte");
} catch (Exception e) {
e.printStackTrace();

}
}
}

class DirFilter2 implements FilenameFilter {
private Pattern pattern;

public DirFilter2(String regex) {

pattern = Pattern.compile(regex);
}

public boolean accept(File dir, String name) {

return pattern.matcher(name).matches();

}
}

输出式样:

[test.txt] has 11 byte

总结:写第一个题目时候想做一个文件内容匹配的小项目,这个和我之前写了一个双向过滤有点相似,可以做一个文件过滤系统,对内容匹配进行扩展。练习题是《java编程思想》练习题进行扩充,书上推荐是list()参数的内部匿名类,这样程序会变小,但是嵌套关系会觉得代码混乱,我才去分开写两个class类的方式来写。