您的位置:首页 > 编程语言 > Java开发

Java 查找指定文件夹下的所有文件中包含有中文的文件,并抠出中文

2017-04-11 16:43 615 查看
整体的代码运用了IO流,递归的方式遍历文件夹下的文件。特别注意的是一个文件夹下包含了多种的不同格式的文件。需要对不同的文件格式进行文件编码格式的转换。

需要导入三个JAR包,下载地址见评论

chardet.jar

cpdetector_1.0.10.jar

antlr-2.7.6.jar

public class FindFile {
static int fileCount = 0;//文件总数
static int wrong = 0 ;//含有中文字符的文件数
static String regEx = "[\u4e00-\u9fa5]";  //匹配中文正则
static Pattern pat = Pattern.compile(regEx);
static FileOutputStream fos = null;
static OutputStreamWriter osw = null;
}
public static void main(String[] args){
Scanner sc = null;
//long a = System.currentTimeMillis();

try {
//每次重新执行的时候删除上次写入的文件
File file = new File("f:\\FileCH.txt");
file.delete();

System.out.println("输入文件路径: ");
//读取输入的路径
sc = new Scanner(System.in);
String filePath = sc.nextLine();
//打开输出流
fos = new FileOutputStream(new File("f:\\FileCH.txt"),true);
osw = new OutputStreamWriter(fos,"UTF-8");

//refreshFileList("f:\\wk");
//开始检查文件
refreshFileList(filePath);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fos.close();
osw.close();
sc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//refreshFileList("E:\\workspace\\test\\ognl\\enhance");

//System.out.print("运行时间为 ");
//System.out.println(System.currentTimeMillis() - a);
//输出检查结果
System.out.println("处理了"+fileCount+" 个文件"+wrong+"包含的字符已存储到f:\\FileCH.txt文件");
}
//递归查找文件
private static void refreshFileList(String strPath) throws IOException {
File dir = new File(strPath);
File[] files = dir.listFiles();

if (files == null)
return;
for (int i = 0; i < files.length; i++) {
System.out.println("第"+i+"个文件");
int flag = 0 ;
if (files[i].isDirectory()) {
refreshFileList(files[i].getAbsolutePath());
} else {
fileCount++;
String strFileName = files[i].getAbsolutePath().toLowerCase();
//System.out.println(getFileEncode(files[i].getAbsolutePath())+" ----" +files[i].getName());
//截取文件格式
String  fileName = strFileName.substring(strFileName.lastIndexOf(".")+1,strFileName.length());
//排除不需要扫描的文件
if(fileName.equals("rar") || fileName.equals("jpg") || fileName.equals("png") || fileName.equals("jar") || fileName.equals("doc") || fileName.equals("xls") || fileName.equals("gif") || fileName.equals("wmz")){
continue;
}
//不知为何  两种方法判断的时候都会吧class文件和jar文件当做是含有中文字符的文件
//所以此处排除掉这class文件和jar文件不参与判断
if(!"class".equals(fileName.toLowerCase())){
//开始输入文件流,检查文件
String enCode = getFileEncode(files[i].getAbsolutePath());
if("void".equals(enCode)){
enCode="UTF-8";
}if("windows-1252".equals(enCode)){
enCode="GBK";
}
FileInputStream fis = new FileInputStream(files[i].getAbsolutePath());
InputStreamReader in = new InputStreamReader(fis,enCode);
BufferedReader br = new BufferedReader(in);
//用于记录行数  确定文件哪一行有中文
int lineCount = 0 ;
String line = null;
//逐行检查文件
while((line = br.readLine())!=null){
/////使用正则表达式进行判断
lineCount++ ;
char[] charArray = line.toCharArray();
for (int k = 0; k < charArray.length; k ++) {
if ((charArray[k] >= 0x4e00) && (charArray[k] <= 0x9fbb)) {
//每行进行扫描,用正则判断含有中文的行
Pattern p = Pattern.compile("([\u4e00-\u9fa5]+)");
String mv = "";
//正则判断
Matcher m = p.matcher( line );
//遍历含有中文的行。并取出中文
while (m.find()) {
mv += m.group(0);
}
//将含有中文的文件名称和中文所在行数写入文件夹
osw.write(files[i].getAbsolutePath()+" ------- 第"+lineCount+"行<===>"+mv+"\r\n");
osw.flush();
flag ++ ;
//wrong++;
if(flag!=0) k =charArray.length ;
}

}
}
//flag!=0 说明该文件中含有中文
if(flag!=0) wrong++ ;
br.close();
in.close();
fis.close();
}
}
}
}
//检查文件类型
public static String getFileEncode(String path) {
/*
* detector是探测器,它把探测任务交给具体的探测实现类的实例完成。
* cpDetector内置了一些常用的探测实现类,这些探测实现类的实例可以通过add方法 加进来,如ParsingDetector、
* JChardetFacade、ASCIIDetector、UnicodeDetector。
* detector按照“谁最先返回非空的探测结果,就以该结果为准”的原则返回探测到的
* 字符集编码。使用需要用到三个第三方JAR包:antlr.jar、chardet.jar和cpdetector.jar
* cpDetector是基于统计学原理的,不保证完全正确。
*/
CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
/*
* ParsingDetector可用于检查HTML、XML等文件或字符流的编码,构造方法中的参数用于
* 指示是否显示探测过程的详细信息,为false不显示。
*/
detector.add(new ParsingDetector(false));
/*
* JChardetFacade封装了由Mozilla组织提供的JChardet,它可以完成大多数文件的编码
* 测定。所以,一般有了这个探测器就可满足大多数项目的要求,如果你还不放心,可以
* 再多加几个探测器,比如下面的ASCIIDetector、UnicodeDetector等。
*/
detector.add(JChardetFacade.getInstance());// 用到antlr.jar、chardet.jar
// ASCIIDetector用于ASCII编码测定
detector.add(ASCIIDetector.getInstance());
// UnicodeDetector用于Unicode家族编码的测定
detector.add(UnicodeDetector.getInstance());
java.nio.charset.Charset charset = null;
File f = new File(path);
try {
charset = detector.detectCodepage(f.toURI().toURL());
} catch (Exception ex) {
ex.printStackTrace();
}
if (charset != null)
return charset.name();
else
return null;
}


参考博客 http://blog.csdn.net/luojia_wang/article/details/9665953
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  io流 java 递归 编码
相关文章推荐