欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java检查文件夹中含有中文的文件(判断文件编码方式)

程序员文章站 2024-02-19 12:36:40
...
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import java.util.regex.Pattern;
import cpdetector.io.ASCIIDetector;
import cpdetector.io.CodepageDetectorProxy;
import cpdetector.io.JChardetFacade;
import cpdetector.io.ParsingDetector;
import cpdetector.io.UnicodeDetector;


public class CheckCN {
	 
	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("D:\\cnFile.txt");
		    	file.delete();
		    	

		    	System.out.println("Please input the path as 'E:\\workspace\\jc6' : ");
		        //读取输入的路径
		    	sc = new Scanner(System.in);
		    	String filePath = sc.nextLine();
		    	//打开输出流
		    	fos = new FileOutputStream(new File("D:\\cnFile.txt"),true);
		    	osw = new OutputStreamWriter(fos,"UTF-8");
		    	
				//refreshFileList("E:\\workspace\\jc6");
		    	//开始检查文件
		    	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+" files were checked , and "+wrong+" files containing the Chinese ,please check D:\\cnFile.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++) {
			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());
				//不知为何  两种方法判断的时候都会吧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++ ;
			    	/*Matcher matcher = pat.matcher(line);     
			        if (matcher.find())    {    
			        	//将含有中文的文件名称和中文所在行数写入文件夹
			        	osw.write(files[i].getAbsolutePath()+" ------- containing the Chinese at line "+lineCount+"\r\n");
			        	osw.flush();
			        	//System.out.println(files[i].getAbsolutePath()+"have china");
			        	 flag ++ ;
	    	            
			        }  */ 
			    	//////不适用正则表达式判断   两种判断方法在效率上不相上下
			    	     char[] charArray = line.toCharArray();  
			    	        for (int k = 0; k < charArray.length; k ++) {  
			    	          if ((charArray[k] >= 0x4e00) && (charArray[k] <= 0x9fbb)) {  
			    	            	//将含有中文的文件名称和中文所在行数写入文件夹
			    	            	osw.write(files[i].getAbsolutePath()+" ------- containing the Chinese at line "+lineCount+"\r\n");
			        	            osw.flush();
			    	                flag ++ ;
			    	                //wrong++;
			    	                if(flag!=0) k =charArray.length ;
			    	            }  
			    	       /*    byte[] bytes=(""+charArray[k]).getBytes(); 
			    	            if(bytes.length==2){ 
			    	            	int[] ints=new int[2]; 
			    	            	ints[0]=bytes[0]& 0xff; 
			    	            	ints[1]=bytes[1]& 0xff; 
			    	            	if(ints[0]>=0x81 && ints[0]<=0xFE && ints[1]>=0x40 && ints[1]<=0xFE){ 
			    	            		// isGB2312=true; 
			    	            		//将含有中文的文件名称和中文所在行数写入文件夹
				    	            	osw.write(files[i].getAbsolutePath()+" ------- containing the Chinese at line "+lineCount+"\r\n");
				        	            osw.flush();
				    	                flag ++ ;
			    	            	} 
			    	            	  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;
 	}
}