[Java] 纯文本查看 复制代码
package com.itheima.file;
/**
* 文本内容查找工具类,可以在查找一个目录下所有文件中查找指定的文本,要查找的文本可以是多行,但需要是一个字符串
* 查找时,可以指定不同类型文件的编码,如果没有指定文件编码,将使用平台默认编码进行解码
* 也可以传入文件名过滤器,如果不传文件名过滤器,将查找所有文件中的内容
* @author Administrator
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class Find {
private static final FilenameFilter defaultFilter ;
private static final Map<String,String> defaultCharsetOfFileType;
static {
defaultFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return true;
}
};
defaultCharsetOfFileType = new HashMap<>();
defaultCharsetOfFileType.put("default", System.getProperty("file.encoding"));
}
/**
* 用于测试工具类,本不应该写在这里,只是为了方便
* @param args
*/
public static void main(String[] args) {
File root = new File("C:\\Users\\Administrator\\Desktop");
String info = "任意一个";
HashMap<String,String> charsetOfFileType = new HashMap<>();
charsetOfFileType.put("default", "gbk");
charsetOfFileType.put(".md", "utf-8");
ArrayList<Map.Entry<File, Integer>> al = find(root, charsetOfFileType, info, new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.matches("^.*\\.(txt$)?(md$)?(java$)?") || new File(dir, name).isDirectory();
}
});
for (Entry<File, Integer> en : al) {
System.out.println( en.getKey() + " : " + en.getValue() );
}
}
/**
* 查找root文件中或者root目录下所有的文件,通过默认编码打开,查找指定的文本,查找到的文件和对应行数存入集合中返回
* @param root 要查找的文件或者目录
* @param info 要查找的文本
* @return 一个ArrayList集合,以Map.Entry作为元素存放查询结果,Map.Entry中是文件和行数的对应关系
*/
public static ArrayList<Map.Entry<File, Integer>> find(File root, String info) {
return find(root, defaultCharsetOfFileType, info);
}
/**
* 查找root文件中或者root目录下所有过滤后的文件中,通过默认编码打开,查找指定的文本,查找到的文件和对应行数存入集合中返回
* @param root 要查找的文件或者目录
* @param info 要查找的文本
* @param filter 文件名过滤器
* @return 一个ArrayList集合,以Map.Entry作为元素存放查询结果,Map.Entry中是文件和行数的对应关系
*/
public static ArrayList<Map.Entry<File, Integer>> find(File root, String info, FilenameFilter filter) {
return find(root, defaultCharsetOfFileType, info, filter);
}
/**
* 查找root文件中或者root目录下所有的文件,通过指定编码打开,查找指定的文本,查找到的文件和对应行数存入集合中返回
* @param root 要查找的文件或者目录
* @param charsetOfFileType 一个Map集合,存放的是后缀名和编码的键值对
* @param info 要查找的文本
* @return 一个ArrayList集合,以Map.Entry作为元素存放查询结果,Map.Entry中是文件和行数的对应关系
*/
public static ArrayList<Map.Entry<File, Integer>> find(File root, Map<String,String> charsetOfFileType, String info) {
return find(root, charsetOfFileType, info, defaultFilter);
}
/**
* 递归查找root文件中或者root目录下所有过滤后的文件中,通过指定编码打开,查找指定的文本,查找到的文件和对应行数存入集合中
* @param root 要查找的文件或者目录
* @param charsetOfFileType 一个Map集合,存放的是后缀名和编码的键值对
* @param infos 要查找的文本
* @param filter 文件名过滤器
* @return 一个ArrayList集合,以Map.Entry作为元素存放查询结果,Map.Entry中是文件和行数的对应关系
*/
public static ArrayList<Map.Entry<File, Integer>> find(File root, Map<String,String> charsetOfFileType, String info, FilenameFilter filter) {
ArrayList<Map.Entry<File, Integer>> al = new ArrayList<>();
String nl = System.getProperty("line.separator");
while( info.startsWith(nl) ) {
info = info.substring(nl.length());
}
if( !"".equals(info) ) {
String infos[] = info.split( nl );
find(root, charsetOfFileType, infos, filter, al);
}
return al;
}
/**
* 递归查找root文件中或者root目录下所有过滤后的文件中,通过指定编码打开,查找指定的文本,查找到的文件和对应行数存入集合中
* @param root 要查找的文件或者目录
* @param charsetOfFileType 一个Map集合,存放的是后缀名和编码的键值对
* @param infos 要查找的文本数组
* @param filter 文件名过滤器
* @param al 一个ArrayList集合,以Map.Entry作为元素存放查询结果,Map.Entry中是文件和行数的对应关系
*/
private static void find(File root, Map<String,String> charsetOfFileType, String[] infos, FilenameFilter filter, ArrayList<Map.Entry<File, Integer>> al) {
if( root.isFile() ) {
LineNumberReader lnr = null;
try {
String suf = getSuffix(root);
if( suf == null || ".".equals(suf) || "".equals(suf) )
suf = "default";
String charset = charsetOfFileType.get(suf);
if( charset == null )
charset = System.getProperty("file.encoding");
lnr = new LineNumberReader(new InputStreamReader(new FileInputStream(root),charset));
for(String line; (line = lnr.readLine()) != null ; ) {
if( infos.length == 1 ) {
if( line.contains( infos[0] ) ) {
addToArrayList(al, root, lnr.getLineNumber());
}
} else {
while( line != null && line.endsWith( infos[0] ) ) {
int t_linenumber = lnr.getLineNumber();
for(int i=1 ;( line = lnr.readLine()) != null ; i++) {
if( i == infos.length - 1 ) {
if( line.startsWith( infos[i] ) ) {
addToArrayList(al, root, t_linenumber);
}
break;
} else {
if( !line.equals( infos[i] ) ) {
break;
}
}
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if( lnr != null ) {
try {
lnr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else if ( root.isDirectory() ) {
File[] files = root.listFiles(filter);
if( files == null )
return;
for( File f : files ) {
find(f, charsetOfFileType, infos, filter, al);
}
}
}
/*
* 获取文件后缀名,如果没有后缀则返回空字符串
*/
private static String getSuffix(File file) {
String name = file.getName();
int index = name.lastIndexOf('.');
if( index < 0 )
return "";
return name.substring(index);
}
/*
* 将File和int数据作为一个键值对,存入ArrayList<Map.Entry<File,Integer>>集合
*/
private static void addToArrayList(ArrayList<Map.Entry<File, Integer>> al, final File file, final int lineNumber) {
al.add(new Entry<File, Integer>() {
private File k = file;
private Integer v = lineNumber;
public Integer setValue(Integer value) {
Integer _ov = v;
v = value;
return _ov;
}
public Integer getValue() {
return v;
}
public File getKey() {
return k;
}
});
}
}