ファイル比較 8、シングルスレッド読み取り、マルチスレッド比較、比較プログレスバー、比較結果 Excel ファイルエクスポート、受け入れ可能

導入

文件对比其实是某个大项目的一个小部分功能的实现,
为了实现这个功能,我思路与想法很多都直接以blog的形式写了出来,可能部分会有缺漏(自认为无伤大雅),
我把这个功能单独拆出来(已经将部分信息隐去,你可自定包结构引入),
你可以做成jar包在linux服务器上单独使用也可以结合到你的业务当中,
技术不复杂但各种有趣的点很多,无论是多线程应用,md5加密,文件读取,文件递归,全局变量的应用
进度条的实现,还是以excel的形式导出结果 。

プロジェクト構造のプレビュー

ここに画像の説明を挿入

ベース

ユーティリティ

スレッド使用率の比較

import java.io.File;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CompareThreadUtil {
    
    
    public static int i;//当前文件个数
    private CountDownLatch latch;
    private CyclicBarrier barrier;
    private LinkedList linkedList = new LinkedList();//总
    private LinkedList<Fc> linkedList1 = new LinkedList<Fc>();//读取路径1中的所有的文件
    private LinkedList<Fc> linkedList2 = new LinkedList<Fc>();//读取路径2中的所有的文件
    private Lock lock = new ReentrantLock();
    private List listoneNot1 = new ArrayList<Fc>(); //存放数据一缺失的数据
    private List listoneNot2 = new ArrayList<Fc>(); //存放数据二缺失的数据
    private List listoneNot3 = new ArrayList<Fc>(); //存放数据二缺失的数据

    private Object numberLock = new Object();
    private boolean lockboo = false;
    private List<String> list;


    private File root1;
    private File root2;
    private String dirName1;
    private String dirName2;


    private ReadFile2 trFile1;
    private Boolean[] StopIt;


    public CompareThreadUtil(CountDownLatch latch, CyclicBarrier barrier,
                             List list,
                             List<Fc> listoneNot1, List<Fc> listoneNot2,
                             List<Fc> listoneNot3, File root1, File root2,
                             String dirName1, String dirName2, ReadFile2 trFile1, Boolean[] stop

    ) {
    
    
        this.latch = latch;
        this.barrier = barrier;

        this.list = list;
        this.listoneNot1 = listoneNot1;
        this.listoneNot2 = listoneNot2;
        this.listoneNot3 = listoneNot3;
        this.root1 = root1;
        this.root2 = root2;
        this.dirName1 = dirName1;
        this.dirName2 = dirName2;

        this.trFile1 = trFile1;
        this.StopIt = stop;
    }


    public void addFileLevelAfter(int currentID, Integer percentagesum1, int[] i) {
    
    

        File[] file = new File[1];
        File f0File = null;


        try {
    
    
            while (true) {
    
    
                trFile1.getFileInfo(file);
                f0File = file[0];
                if (!StopIt[0] && f0File == null) {
    
    
                    System.out.println("读取线程结束,线程" + currentID + "已获取不到文件,线程停止!");
                    break;
                }
                if (f0File != null) {
    
    
                    addPercent(i);
                    NumberFormat numberFormat = NumberFormat.getNumberInstance();
                    numberFormat.setMaximumFractionDigits(2);
                    String result = numberFormat.format((float) i[0] / (float) percentagesum1 * 100);
                    FileComparesServiceImpl.percentage1 = result + "%";
                    FileComparesServiceImpl.syncCurrentName1 = f0File.getName();
                    System.out.println("当前为检测线程" + currentID + "读取的文件为第" + i[0] + "个文件" + "文件名为" + f0File + "   文件总数为" + percentagesum1);
                    System.out.println("此时百分比为" + FileComparesServiceImpl.percentage1);


                    if (String.valueOf(f0File).startsWith(dirName1)) {
    
    
                        File file2 = new File(f0File.toString().replace(dirName1, dirName2));
                        if (file2.exists()) {
    
    
                            if (f0File.lastModified() != file2.lastModified()) {
    
    
                                Fc fc1 = new Fc();
                                fc1.setType("两数据源对比发生修改的文件");
                                fc1.setPath(f0File.getPath());
                                fc1.setLastmodified(String.valueOf(f0File.lastModified()));
                                fc1.setMd5(getMD5File(f0File));
                                listoneNot3.add(fc1);

                            }
                        } else {
    
    
                            Fc fc = new Fc();
                            fc.setType("数据源1发生删除的文件");
                            fc.setPath(f0File.getPath());
                            fc.setLastmodified(String.valueOf(f0File.lastModified()));
                            fc.setMd5(getMD5File(f0File));

                            listoneNot1.add(fc);
                        }
                    } else {
    
    
                        File file1 = new File(f0File.toString().replace(dirName2, dirName1));
                        if (file1.exists()) {
    
    
                            if (f0File.lastModified() != file1.lastModified()) {
    
    
                                Fc fc1 = new Fc();
                                fc1.setType("两数据源对比发生修改的文件");
                                fc1.setPath(f0File.getPath());
                                fc1.setLastmodified(String.valueOf(f0File.lastModified()));
                                fc1.setMd5(getMD5File(f0File));
                                listoneNot3.add(fc1);

                            }
                        } else {
    
    
                            Fc fc = new Fc();
                            fc.setType("数据源2发生删除的文件");
                            fc.setPath(f0File.getPath());
                            fc.setLastmodified(String.valueOf(f0File.lastModified()));
                            fc.setMd5(getMD5File(f0File));
                            listoneNot2.add(fc);
                        }
                    }
                }

            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            System.out.println("线程" + currentID + " 正常停止!");

        } finally {
    
    

            latch.countDown();
        }

    }

    public static synchronized void addPercent(int[] i) {
    
    
        try {
    
    
            i[0]++;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

}

エクセルユーティリティ

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.context.annotation.ComponentScan;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class ExcelUtil {
    
    

	/**
	 * 导出并下载
	 * 
	 * @param response
	 *            response对象
	 * @param data
	 *            数据源(对象)
	 * @param title
	 *            每一列的标题
	 * @param columns
	 *            需要导出的字段
	 * @param excelName
	 *            excel名字
	 */
	public static void exportData(HttpServletResponse response, List<?> data, List<String> title, List<String> columns,
                                  String excelName) {
    
    
		response.setContentType("application/vnd.ms-excel");
		String codedFileName = null;
		OutputStream fOut = null;
		// 进行转码,使其支持中文文件名
		try {
    
    
			codedFileName = java.net.URLEncoder
					.encode(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")", "UTF-8");
		} catch (UnsupportedEncodingException e1) {
    
    
			e1.printStackTrace();
		}
		response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");

		HSSFWorkbook wb = new HSSFWorkbook();
		MyExportExcel myExportExcel = new MyExportExcel();
		myExportExcel.setHssfWorkbook(wb);
		// 设置标题
		myExportExcel.setExcelTitle(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")",
				title.size()-1);
		// 设置列名
		myExportExcel.setNormalTwoRow(title);

		if (data.size() < 1) {
    
    
			myExportExcel.setNullData(columns.size()-1);
		} else {
    
    
			try {
    
    
				//导出数据
				myExportExcel.setExcelData2(data, columns);
			} catch (IllegalAccessException e) {
    
    
				e.printStackTrace();
			}
		}
		try {
    
    
			fOut = response.getOutputStream();
			wb.write(fOut);
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			try {
    
    
				fOut.flush();
				fOut.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * @param response
	 * @param data (map)
	 * @param title
	 * @param columns
	 * @param excelName
	 */
	public static void exportData1(HttpServletResponse response, List<?> data, List<String> title, List<String> columns,
                                   String excelName) {
    
    
		response.setContentType("application/vnd.ms-excel");
		String codedFileName = null;
		OutputStream fOut = null;
		// 进行转码,使其支持中文文件名
		try {
    
    
			codedFileName = java.net.URLEncoder
					.encode(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")", "UTF-8");
		} catch (UnsupportedEncodingException e1) {
    
    
			e1.printStackTrace();
		}
		response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");

		HSSFWorkbook wb = new HSSFWorkbook();
		MyExportExcel myExportExcel = new MyExportExcel();
		myExportExcel.setHssfWorkbook(wb);
		// 设置标题
		myExportExcel.setExcelTitle(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")",
				title.size()-1);
		// 设置列名
		myExportExcel.setNormalTwoRow(title);

		if (data.size() < 1) {
    
    
			myExportExcel.setNullData(columns.size()-1);
		} else {
    
    
			try {
    
    
				//导出数据
				myExportExcel.setExcelData3(data, columns);
			} catch (IllegalAccessException e) {
    
    
				e.printStackTrace();
			}
		}
		try {
    
    
			fOut = response.getOutputStream();
			wb.write(fOut);
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			try {
    
    
				fOut.flush();
				fOut.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}

}

MD5


import java.io.File;
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;

/**
 * Md5工具类
 *
 * @version 20161209
 */
public class Md5 {
    
    

	/**
	 * 加密字符串
	 */
	public static String stringToMd5(String str) throws Exception {
    
    
		StringBuffer userpass = new StringBuffer("");
		if (str != null && !str.equals("")) {
    
    
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte b[] = md.digest();
			int i;
			userpass = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
    
    
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					userpass.append("0");
				userpass.append(Integer.toHexString(i));
			}
		}
		return userpass.toString();
	}

	/**
	 * 获取文件MD5
	 */
	public static String getMD5File(File file) {
    
    

		String inputFile = file.getPath();
		String result = "";
		// 缓冲区大小
		int bufferSize = 256 * 1024;
		FileInputStream fis = null;
		DigestInputStream dis = null;

		try {
    
    
			// 拿到一个MD5转换器
			MessageDigest md = MessageDigest.getInstance("MD5");

			// 使用DigestInputStream
			fis = new FileInputStream(inputFile);
			dis = new DigestInputStream(fis, md);

			// read 过程中进行MD5处理,直到读完文件
			byte[] buffer = new byte[bufferSize];
			while (dis.read(buffer) > 0)
				;

			// 获取最终的MessageDigest
			md = dis.getMessageDigest();
			// 拿到结果,也是字节数组,包含16个元素
			byte[] resultByteArray = md.digest();
			// 同样,把字节组转换成字符串
			result = byteArrayToHex(resultByteArray);

		} catch (Exception e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			try {
    
    
				dis.close();
				fis.close();
			} catch (Exception e) {
    
    
				e.printStackTrace();
			}
		}
		return result;
	}

	// 将字节数组转换成字符串
	private static String byteArrayToHex(byte[] b) {
    
    
		String hs = "";
		String stmp = "";
		for (int i = 0; i < b.length; i++) {
    
    
			stmp = (Integer.toHexString(b[i] & 0xFF));
			if (stmp.length() == 1) {
    
    
				hs = hs + "0" + stmp;
			} else {
    
    
				hs = hs + stmp;
			}
			if (i < b.length - 1) {
    
    
				hs = hs + "";
			}
		}
		return hs;
	}

	public static void main(String[] args) {
    
    
		File files = new File("F:\\学习资料\\Spring Cloud微服务实战.pdf");
		System.out.println(getMD5File(files));
	}
}

読み取りファイル2


import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReadFile2 {
    
    
    //    private static final Logger logger = Logger.getLogger(ReadFile.class);
    private CountDownLatch latch;
    private CyclicBarrier barrier;
    private LinkedList<File> linkedList = new LinkedList();//总


    private Lock lock = new ReentrantLock();
    private Object numberLock = new Object();
    private boolean lockboo = false;
    private List<String> list;


    private File root1;
    private File root2;
    private String dirName1;
    private String dirName2;


    private Boolean[] StopIt;


    public ReadFile2(CountDownLatch latch, CyclicBarrier barrier,
                     List list,
                     String dirName1, String dirName2,
                     Boolean[] stop

    ) {
    
    
        this.latch = latch;
        this.barrier = barrier;
        this.list = list;

        this.dirName1 = dirName1;
        this.dirName2 = dirName2;

        this.StopIt = stop;

    }


    // 读取文件信息
    public void readFile() {
    
    
        try {
    
    

            readFileInfo(new File(list.get(0)));
            readFileInfo(new File(list.get(1)));

//            logger.info("读取文件线程正常停止!");
            System.out.println("读取文件线程正常停止!");
        } catch (Exception e) {
    
    

            System.out.println("错误信息!" + e);
        } finally {
    
    
            StopIt[0] = false;
            latch.countDown();
        }
    }


    private void readFileInfo(File root) {
    
    
        if (root.exists()) {
    
    
            if (root.isDirectory()) {
    
    
                File[] files = root.listFiles();
                if (files != null) {
    
    
                    for (int i = 0; i < files.length; i++) {
    
    

                        if (files[i].isFile()) {
    
    
                            addFile(files[i]);

                        } else if (files[i].isDirectory()) {
    
    
                            readFileInfo(files[i]);
                        }
                        files[i] = null;
                    }
                }
                files = null;
            } else if (root.isFile()) {
    
    
                addFile(root);
            }
        }
    }


    private void addFile(File file) {
    
    
        lock.lock();
        try {
    
    
            linkedList.addLast(file);

        } catch (Exception e) {
    
    
            System.out.println("添加文件出错:" + e);
        } finally {
    
    
            lock.unlock();
//            try {
    
    
//                if (linkedList.size() >= 10000) {
    
    
//                    synchronized (numberLock) {
    
    
//                        lockboo = true;
//                        numberLock.wait();
//                    }
//                }
//            } catch (Exception e2) {
    
    
                logger.error("锁出错:", e2);
//                System.out.println("锁出错" + e2);
//            }
        }
    }


    public void getFileInfo(File[] file) {
    
    
        lock.lock();
        try {
    
    
            file[0] = linkedList.pollFirst();

            if (lockboo && linkedList.size() <= 1000) {
    
    
                synchronized (numberLock) {
    
    
                    lockboo = false;
                    numberLock.notify();
                }
            }
        } catch (Exception e) {
    
    
//            logger.error("获取文件出错:", e);
            System.out.println("获取文件出错:" + e);
        } finally {
    
    
            lock.unlock();
        }
    }

}

使用量


import eu.bitwalker.useragentutils.UserAgent;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util implements FilenameFilter {
    
    
    private static final Logger logger = LoggerFactory.getLogger(Util.class);

    private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private String suffix;

    public Util(String suffix) {
    
    
        super();
        this.suffix = suffix;
    }

    /**
     * 文件大小格式化
     *
     * @param length 文件大小
     */
    public static String fileSizeFormat(long length) {
    
    
        DecimalFormat df = new DecimalFormat("#0.0");
        float size = (float) length / 1024;
        String sumFilesize = "";

        if (size >= 0 && size < 1) {
    
    
            sumFilesize = length + " B";
        } else if (size >= 1 && size < 1024) {
    
    
            sumFilesize = df.format(size) + " K";
        } else if (size >= 1024) {
    
    
            size = size / 1024;
            if (size >= 1 && size < 1024) {
    
    
                sumFilesize = df.format(size) + " M";
            } else if (size >= 1024 && size < 1048576) {
    
    
                size = size / 1024;
                sumFilesize = df.format(size) + " G";
            } else if (size >= 1048576) {
    
    
                size = size / 1024 / 1024;
                sumFilesize = df.format(size) + " T";
            }
        }

        return sumFilesize;
    }

    /**
     * 文件大小格式化  传入的单位是GB
     *
     * @param length 文件大小
     */
    public static String fileSizeFormat2(long length) {
    
    
        DecimalFormat df = new DecimalFormat("#0.0");
        float size = (float) length / 1024;
        String sumFilesize = "";

        if (size >= 0 && size < 1) {
    
    
            sumFilesize = length + " G";
        } else if (size >= 1) {
    
    
            sumFilesize = df.format(size) + " T";
        }

        return sumFilesize;
    }

    /**
     * 文件拷贝
     *
     * @param f1Path 源路径
     * @param f2Path 目标路径
     */
    public static boolean fileCopy(String f1Path, String f2Path) {
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File f1 = null;
        File f2 = null;

        int outputSize = 1024000;// 默认1M
        boolean boo = false;

        try {
    
    
            f1 = new File(f1Path);
            f2 = new File(f2Path);

            File pfile = new File(f2.getParent());
            if (!pfile.exists()) {
    
    
                pfile.mkdirs();
            }

            if (f1.length() > 104857600) {
    
    
                outputSize = 10240000; // 文件大于100M,修改outputSize为10240000
            }

            FileInputStream fis = new FileInputStream(f1);
            FileOutputStream fos = new FileOutputStream(f2);

            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            byte[] b = new byte[outputSize];
            int len = 0;
            while ((len = bis.read(b, 0, b.length)) != -1) {
    
    
                bos.write(b, 0, len);
            }

            bos.flush();
            boo = true;
        } catch (Exception e) {
    
    
            boo = false;
            logger.error("文件" + f1Path + "拷贝失败,原因:", e);
        } finally {
    
    
            try {
    
    
                if (bos != null)
                    bos.close();
                if (bis != null)
                    bis.close();
            } catch (IOException e) {
    
    
                boo = false;
                e.printStackTrace();
            }

            if (boo) {
    
    
                // 修改时间戳
                boo = f2.setLastModified(f1.lastModified());
            }
        }

        return boo;
    }

    /**
     * 文件拷贝 20181110
     *
     * @param f1File 源路径
     * @param f2File 目标路径
     */
    public static boolean fileCopyNew(File f1File, File f2File) {
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        int outputSize = 1024000;// 默认1M
        boolean boo = false;

        try {
    
    
            File pfile = f2File.getParentFile();
            if (!pfile.exists()) {
    
    
                pfile.mkdirs();
            }
            pfile = null; //回收对象

            if (f1File.length() > 104857600) {
    
    
                outputSize = 10240000; // 文件大于100M,修改outputSize为10240000
            }

            FileInputStream fis = new FileInputStream(f1File);
            FileOutputStream fos = new FileOutputStream(f2File);

            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            byte[] b = new byte[outputSize];
            int len = 0;
            while ((len = bis.read(b, 0, b.length)) != -1) {
    
    
                bos.write(b, 0, len);
            }

            bos.flush();
            boo = true;
        } catch (Exception e) {
    
    
            boo = false;
            logger.error("文件" + f1File.getPath() + "拷贝失败,原因:", e);
        } finally {
    
    
            try {
    
    
                if (bos != null)
                    bos.close();
                if (bis != null)
                    bis.close();
            } catch (IOException e) {
    
    
                boo = false;
                e.printStackTrace();
            }

            if (boo) {
    
    
                // 修改时间戳
                boo = f2File.setLastModified(f1File.lastModified());
            }
        }

        return boo;
    }


    /**
     * 下载打包的文件
     *
     * @param file
     * @param response
     * @param isDelete 是否删除源文件
     */
    public static void downloadZip(File file, HttpServletResponse response, boolean isDelete) {
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        boolean boo = false;

        try {
    
    
            response.reset();
            response.setCharacterEncoding("ISO8859-1");
            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes("gb2312"), "ISO8859-1"));
            response.setContentType("application/octet-stream");
            response.setHeader("Connection", "close");
            response.setContentLength((int) file.length());

            bis = new BufferedInputStream(new FileInputStream(file.getPath()));
            bos = new BufferedOutputStream(response.getOutputStream());

            byte[] b = new byte[10240];
            int len = 0;
            while ((len = bis.read(b, 0, b.length)) != -1) {
    
    
                bos.write(b, 0, len);
            }

            bos.flush();
            boo = true;
        } catch (Exception e) {
    
    
            boo = false;
        } finally {
    
    
            try {
    
    
                if (bos != null)
                    bos.close();
                if (bis != null)
                    bis.close();
            } catch (IOException e) {
    
    
                boo = false;
            }

            if (boo && isDelete) {
    
    
                file.delete();
            }
        }
    }

    /**
     * 文件打包
     *
     * @param filePathList 需要打包的文件路径集合
     * @param targetPath   目的路径
     * @param password     打包密码
     */
    public static boolean collectFiles(List<String> filePathList, String targetPath, String password) {
    
    
        try {
    
    
            File targetPathParent = new File(new File(targetPath).getParent());
            if (!targetPathParent.exists()) {
    
    
                targetPathParent.mkdirs();
            }

            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_FASTEST);
            if (password != null && !password.equals("")) {
    
    
                parameters.setEncryptFiles(true);
                parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
                parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
                parameters.setPassword(password);
            }

            ZipFile zipFile = new ZipFile(targetPath);
            zipFile.setFileNameCharset("gbk");

            for (String ss : filePathList) {
    
    
                File file = new File(ss);
                if (file.exists() && file.isDirectory()) {
    
    
                    zipFile.addFolder(file, parameters);
                } else if (file.exists() && file.isFile()) {
    
    
                    zipFile.addFile(file, parameters);
                }
            }
        } catch (ZipException e) {
    
    
            logger.error("文件打包失败,原因:", e);
            return false;
        }

        return true;
    }


    /**
     * 文件解压
     *
     * @param sourceFile 需要解压的文件路径
     * @param targetPath 目的路径
     */
    public static boolean extractFile(String sourceFile, String targetPath) {
    
    
        try {
    
    
            ZipFile zFile = new ZipFile(sourceFile);
            zFile.setFileNameCharset("GBK");

            if (!zFile.isValidZipFile()) {
    
     // 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
                throw new ZipException("压缩文件不合法,可能被损坏.");
            }

            File destDir = new File(targetPath); // 解压目录
            if (destDir.isDirectory() && !destDir.exists()) {
    
    
                destDir.mkdir();
            }

            zFile.extractAll(targetPath);
        } catch (ZipException e) {
    
    
            logger.error("文件解压失败,原因:", e);
            return false;
        }

        return true;
    }

    /**
     * 文件夹删除
     *
     * @param filePath 需要删除的文件夹路径
     */
    public static boolean deleteFiles(String filePath) {
    
    
        boolean flag = true;
        File dirFile = new File(filePath);

        if (!dirFile.exists() || !dirFile.isDirectory()) {
    
    
            return false;
        }

        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
    
    
            if (files[i].isFile()) {
    
    
                File file = new File(files[i].getAbsolutePath());
                flag = file.delete();
                if (!flag)
                    break;
            } else {
    
    
                flag = deleteFiles(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }

        if (!flag)
            return false;
        // 删除当前目录
        if (dirFile.delete()) {
    
    
            return true;
        } else {
    
    
            return false;
        }
    }

    /**
     * 文件剪切
     *
     * @param source 源文件
     * @param target 目标文件
     */
    public static boolean fileShear(String source, String target) {
    
    
        File sourceFile = new File(source);
        boolean flag = true;

        if (!sourceFile.exists()) {
    
    
            return false;
        }

        if (!sourceFile.isDirectory()) {
    
    
            if (fileCopy(source, target)) {
    
    
                flag = sourceFile.delete();
            } else {
    
    
                flag = false;
            }

            return flag;
        } else {
    
    
            File[] files = sourceFile.listFiles();
            for (int i = 0; i < files.length; i++) {
    
    
                String filesPath = files[i].getPath().replace("\\", "/");
                if (files[i].isFile()) {
    
    
                    if (fileCopy(filesPath, filesPath.replace(source, target))) {
    
    
                        flag = files[i].delete();
                    } else {
    
    
                        flag = false;
                    }

                    if (!flag)
                        break;
                } else {
    
    
                    flag = fileShear(filesPath, filesPath.replace(source, target));

                    if (!flag)
                        break;
                }
            }

            if (!flag)
                return false;
            // 删除当前目录
            if (sourceFile.delete()) {
    
    
                return true;
            } else {
    
    
                return false;
            }
        }
    }

    /**
     * 计算百分比
     *
     * @param dividend 被除数
     * @param divisor  除数
     */
	/*public static String getProgressbar(int dividend, int divisor) {
		try {
			int a = dividend / (divisor / 100);
			if (a >= 100) {
				a = 100;
			}
			return a + "";
		} catch (Exception e) {
			return "0";
		}
	}*/


    /**
     * @Description :
     * @Params [dividend, divisor]
     * @Return: java.lang.String
     */
    public static String getProgressbar(int dividend, int divisor) {
    
    

        if (divisor != 0) {
    
    
            NumberFormat numberFormat = NumberFormat.getInstance();
            numberFormat.setMaximumFractionDigits(2);
            return numberFormat.format((float) dividend / (float) divisor * 100);
        } else {
    
    
            return "0";
        }
    }

    /**
     * 获取文件后缀名
     */
    public static String getFileExtension(File file) {
    
    
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
    
    
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
    
    
            return "";
        }
    }

    /**
     * @return
     * @Description 判断是否有汉字
     * @Date 上午 9:05 2019/12/30 0030
     * @Param
     **/
    public static boolean isChinese(String countname) {
    
    
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(countname);
        if (m.find()) {
    
    
            return true;
        }
        return false;
    }


    /**
     * 文件大小格式化
     *
     * @param length 文件大小
     */
    public static String fileSizeFormatToG(double length) {
    
    
        DecimalFormat df = new DecimalFormat("#0.0");
        double size = length / 1024 / 1024 / 1024;
        String sumFilesize = df.format(size);

        return sumFilesize;
    }

    /**
     * @return
     * @Description //备份软件生成ID的工具类
     * @Date 上午 9:50 2019/11/8 0008
     * @Param
     **/
    public static String creatId() {
    
    
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    /**
     * @Auther: 雷硕
     * @Date: 2018/1/23 0014 16:11
     * @Description:百分比转换UTIL num1除数, num2被除数
     */
    public static String transform(Integer num1, Integer num2) {
    
    
        String result;
        // 创建一个数值格式化对象
        if (num1 != 0 && num2 != 0) {
    
    
            NumberFormat numberFormat = NumberFormat.getInstance();

            // 设置精确到小数点后2位

            numberFormat.setMaximumFractionDigits(2);

            result = numberFormat.format((float) num1 / (float) num2 * 100);
        } else {
    
    
            result = "0";
        }


        return result;
    }

    /**
     * @Auther: 雷硕
     * @Date: 2018/1/23 0014 16:11
     * @Description:百分比转换UTIL num1除数, num2被除数
     */
    public static String transform2(Long num1, Long num2) {
    
    
        String result;
        // 创建一个数值格式化对象
        if (num1 != 0 && num2 != 0) {
    
    
            NumberFormat numberFormat = NumberFormat.getInstance();

            // 设置精确到小数点后2位

            numberFormat.setMaximumFractionDigits(0);

            result = numberFormat.format((float) num1 / (float) num2 * 100);
        } else {
    
    
            result = "0";
        }


        return result;
    }

    public static double div(double d1, double d2, int len) {
    
    // 进行除法运算
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    //文件夹剪切
    public static void cutDirOrFile(String sourePath, String originalPath, String recyclePath) {
    
    
        File file = new File(sourePath);
        File[] files = file.listFiles();
        for (File file2 : files) {
    
    
            if (file2.isFile()) {
    
    
                Util.fileCopyNew(file2, new File(file2.toString().replace("\\", "/").replace(originalPath, recyclePath)));
            } else if (file2.isDirectory()) {
    
    
                cutDirOrFile(file2.toString(), originalPath, recyclePath);
            }

        }
    }

    /**
     * 树形结构
     *
     * @param paths
     * @param fileArray
     * @param depotid
     * @param flag
     * @return
     */
    public static JSONArray readFolderToTree(String paths, JSONArray fileArray, String depotid, String flag) {
    
    
        File file = new File(paths);
        String[] filelist = file.list();
        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < filelist.length; i++) {
    
    
            JSONObject fileJson = new JSONObject();
            File readfile = new File(paths + "/" + filelist[i]);
            if (readfile.isDirectory()) {
    
    
                String filepaths = readfile.getPath().replaceAll("\\\\", "/");
                if (!filepaths.endsWith("/")) {
    
    
                    filepaths = filepaths + "/";
                }
                fileJson.put("id", filepaths);
                fileJson.put("pId", paths);
                fileJson.put("name", readfile.getName());
                fileJson.put("state", "closed");
                fileJson.put("isParent", "true");
                JSONObject attributes = new JSONObject();
                attributes.put("filepath", filepaths);
                attributes.put("depotid", depotid);
                attributes.put("flag", flag);
                fileJson.put("attributes", attributes);
                jsonArray.add(fileJson);
            }
        }
        fileArray.addAll(jsonArray);

        return fileArray;
    }

    //生成批次编号
//    public static JSONObject selectFillData(String curr) {
    
    
//        JSONObject obj = new JSONObject();
//        if (StringUtils.isEmpty(curr)) {
    
    
//            curr = DateUtils.getYearMonthDay2() + "00001";
//        } else {
    
    
//            curr = curr.substring(8);
//            int news = Integer.parseInt(curr) + 1;
//            curr = String.valueOf(news);
//            switch (curr.length()) {
    
    
//                case 4:
//                    curr = "0" + curr;
//                    break;
//                case 3:
//                    curr = "00" + curr;
//                    break;
//                case 2:
//                    curr = "000" + curr;
//                    break;
//                case 1:
//                    curr = "0000" + curr;
//            }
//
//            curr = DateUtils.getYearMonthDay2() + curr;
//
//        }
//
//        obj.put("pcbh", curr);
//        return obj;
//    }

    @Override
    public boolean accept(File file, String name) {
    
    
        return !name.endsWith(suffix);
    }

    //截取zip文件夹的名称
    public static String subString(String path) {
    
    
//		String path="/home/henry/Desktop/1.txt";

        String oo = path.substring(path.lastIndexOf("/", path.lastIndexOf("/") - 1) + 1);

        return oo.substring(0, oo.lastIndexOf("/"));
    }

    //不足八位,补足八位
    public static String complementEight(Object a) {
    
    
        String result = a + "";
        if (!(a instanceof Integer)) {
    
    
            return result;
        }
        if (a.toString().length() < 8) {
    
    
            Integer cha = 8 - a.toString().length();
            for (int i = 0; i < cha; i++) {
    
    
                result = "0" + result;
            }
        }
        return result;
    }

    /**
     * 获取加密密钥
     */
    @SuppressWarnings("static-access")
    public static String getKey() {
    
    
        String key = "";

//        com.softkey.jsyunew6 j9 = new com.softkey.jsyunew6();
//        String DevicePath = j9.FindPort(0);
//
//        if (j9.get_LastError() != 0) {
    
    
			logger.info("未在服务器上找到加密锁!");
//        } else {
    
    
//            j9.YRead((short) 0, (short) 1, "98A135F3", "37997F31", DevicePath);
//            short address = 1;// 要读取的字符串在加密锁中储存的起始地址
//            short len = j9.GetBuf(0);// 注意这里的6是长度,要与写入的字符串的长度相同
//            key = j9.YReadString(address, len, "98A135F3", "37997F31", DevicePath);
//
//            if (!key.substring(0, key.indexOf("|")).equals("DMS")) {
    
    
//                key = "";
//            } else {
    
    
//                key = key.substring(key.lastIndexOf("|") + 1, key.length());
//            }
//        }

        return "77NEdEJJK3d396b4wx549LDY56S75bK1";
    }

    public static JSONObject getFileInfo(String filefullpath) {
    
    
        File file = new File(filefullpath);
        String filename;
        String extname = "";
        String filepath;
        int nameindex = filefullpath.lastIndexOf("/");
        filepath = filefullpath.substring(0, nameindex + 1);
        filename = filefullpath.substring(nameindex + 1);
        int extindex = filename.lastIndexOf(".");
        if (extindex != -1) {
    
    
            extname = filename.substring(extindex + 1);
            filename = filename.substring(0, extindex);
        }

        JSONObject obj = new JSONObject();
        obj.put("filepath", filepath);
        obj.put("filename", filename);
        obj.put("extname", extname);

        return obj;
    }

    public static JSONObject getMessage(HttpServletRequest request){
    
    
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        String brower = userAgent.getBrowser().getName();
        String system = userAgent.getOperatingSystem().getName();
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("system",system);
        jsonObject.put("browser",brower);
        return jsonObject;
    }

    /**
     * 读取当前文件夹第一层的文件和文件夹
     *
     * @param filepath
     *            文件夹路径
     * @param array
     *            返回的结果集合
     */
    public static void readCurrentFirstFile(String filepath, List<String> array) {
    
    
        File file = new File(filepath);
        String[] filelist = file.list();
        for (int i = 0; i < filelist.length; i++) {
    
    
            File readfile = new File(filepath + "/" + filelist[i]);
            if (!readfile.isHidden()) {
    
    
                array.add(readfile.getAbsolutePath());

            }
        }
    }

    //获取CPU核心数
    public static Integer getCPUnum(){
    
    
        int i = Runtime.getRuntime().availableProcessors();
        return i;
    }




    /**
     * @param s 源文件
     * @param t 复制到的新文件
     */
    public static boolean fileChannelCopy(File s, File t) {
    
    
        FileInputStream fi = null;
        FileOutputStream fo = null;
        FileChannel in = null;
        FileChannel out = null;
        boolean boo = true;

        int GB = 1024 * 1024 * 1024;//定义GB的计算常量

        try {
    
    
            File pfile = new File(t.getParent());
            if (!pfile.exists()) {
    
    
                pfile.mkdirs();
            }

            fi = new FileInputStream(s);
            fo = new FileOutputStream(t);
            in = fi.getChannel();//得到对应的文件通道
            out = fo.getChannel();//得到对应的文件通道

            if (in.size() / GB >= 2) {
    
    
                ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
                while (in.read(buffer) != -1) {
    
    
                    buffer.flip();
                    out.write(buffer);
                    buffer.clear();
                }
            } else {
    
    
                in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
            }
        } catch (IOException e) {
    
    
            boo = false;
            logger.error("文件" + s.getPath() + "拷贝失败,原因:", e);
        } finally {
    
    
            try {
    
    
                fi.close();
                in.close();
                fo.close();
                out.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }

            if (boo) {
    
    
                // 修改时间戳
                boo = t.setLastModified(s.lastModified());
            }

        }
        return boo;
    }

    /**
     * 获取文件后缀名
     */
    public static String getFileExtensions(String fileName) {
    
    
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
    
    
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
    
    
            return "";
        }
    }


}

コントローラ

ファイル比較コントローラ



import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taiyusoft.tydms.base.util.ExcelUtil;
import com.taiyusoft.tydms.entity.Fc;
import com.taiyusoft.tydms.entity.ResponseForm;
import com.taiyusoft.tydms.service.FileComparesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/***
 * @Param
 * @return
 **/
@RestController
@RequestMapping("/fileComparesimple")
public class FileCompareController {
    
    
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private FileComparesService fileComparesService;

    //调用文件对比
    @RequestMapping("/selectfileComparesimple")
    public void fileComparesimple(String firstpath, String secondpath) {
    
    
        long time1 = System.currentTimeMillis();
        File file1 = new File(firstpath);
        File file2 = new File(secondpath);

        try {
    
    
            if (file1.isFile() || file1.isDirectory() && file2.isFile() || file2.isDirectory()) {
    
    
                fileComparesService.fileComparesimple(firstpath.replace("/","\\"), secondpath.replace("/","\\"));
            }
            long time2 = System.currentTimeMillis();
            int time = (int) ((time2 - time1) / 1000);
            System.out.println("执行了:" + time + "秒!");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }

    /**
     * 进度条初始化
     *
     * @return
     */
    @RequestMapping("/fileComparesinit")
    public ResponseForm fileComparesinit(String firstpath, String secondpath) {
    
    
        ResponseForm responseForm = new ResponseForm();
        Integer sum = 0;
        try {
    
    
            sum = fileComparesService.initPercentage(firstpath, secondpath);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("sum", sum);
            if (sum > 0) {
    
    
                responseForm.setCode("200");
                responseForm.setData(jsonObject);
                responseForm.setMessage(ResponseForm.message.SUCCESS);
            } else {
    
    
                responseForm.setCode("401");
                responseForm.setMessage(ResponseForm.message.FAIL);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            System.out.println(e);
            responseForm.setCode("402");
            responseForm.setMessage(ResponseForm.message.FAIL);


        }
        return responseForm;
    }

    /**
     * 文件对比时间过长时,出现该当前文件进度条百分比
     */
    @RequestMapping("/fileComparesimplePercentage")
    public ResponseForm fileComparesimplePercentage() {
    
    
        ResponseForm responseForm = new ResponseForm();
        JSONObject jsonObject;
        try {
    
    
            jsonObject = fileComparesService.fileComparesimplePercentage();
            responseForm.setData(jsonObject);
            responseForm.setCode("200");
            responseForm.setMessage(ResponseForm.message.SUCCESS);
        } catch (Exception e) {
    
    
            responseForm.setCode("400");
            responseForm.setMessage(ResponseForm.message.FAIL);
        }

        return responseForm;
    }

    /**
     * 文件处理时间过长时,专门获取文件对比结果
     *
     * @return
     */
    @RequestMapping("/getfileCompares")
    public ResponseForm getfileCompares() {
    
    
        ResponseForm responseForm = new ResponseForm();
        JSONObject jsonObject;
        try {
    
    
            jsonObject = fileComparesService.getfileCompares();
            responseForm.setData(jsonObject);
            responseForm.setCode("200");
            responseForm.setMessage(ResponseForm.message.SUCCESS);
        } catch (Exception e) {
    
    
            responseForm.setCode("400");
            responseForm.setMessage(ResponseForm.message.FAIL);
        }

        return responseForm;
    }


    /**
     * 导出excel
     *
     * @return
     */
    @RequestMapping("/exportExcel")
    @ResponseBody
    public String exportExcel(HttpServletResponse response) {
    
    
        ResponseForm responseForm = new ResponseForm();
        String querystr = "";
        String starTime = "";
        String endTime = "";
        JSONObject jsonObject;
        responseForm = getfileCompares();

        ArrayList<Fc> listoneNot1 = new ArrayList<>();
        ArrayList<Fc> listoneNot2 = new ArrayList<>();
        ArrayList<Fc> listoneNot3 = new ArrayList<>();

        JSONObject data = new JSONObject();

        listoneNot1 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("数据源1发生删除的文件");
        listoneNot2 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("数据源2发生删除的文件");
        listoneNot3 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("两数据源对比发生修改的文件");

        ArrayList<Fc> fcs = new ArrayList<>();


        fcs.addAll(listoneNot1);
        fcs.addAll(listoneNot2);
        fcs.addAll(listoneNot3);
for (Fc fc : fcs) {
    
    
    System.out.println(fc);
}
        List<String> list1 = new ArrayList<>();
        list1.add("文件类别");
        list1.add("路径");
        list1.add("最后修改时间");
        list1.add("md5");

        List<String> list2 = new ArrayList<>();
        list2.add("type");
        list2.add("path");
        list2.add("lastmodified");
        list2.add("md5");

        ExcelUtil.exportData(response, fcs, list1, list2, "对比文件结果");

        try {
    
    
            response.getWriter().print("导出成功");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }
}

エンティティ

FC


public class Fc {
    
    
    String type;
    String path;
    String lastmodified;
    String md5;

    public String getPath() {
    
    
        return path;
    }

    public void setPath(String path) {
    
    
        this.path = path;
    }

    public String getLastmodified() {
    
    
        return lastmodified;
    }

    public void setLastmodified(String lastmodified) {
    
    
        this.lastmodified = lastmodified;
    }

    public String getMd5() {
    
    
        return md5;
    }

    public void setMd5(String md5) {
    
    
        this.md5 = md5;
    }

    public String getType() {
    
    
        return type;
    }

    public void setType(String type) {
    
    
        this.type = type;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Fc fc = (Fc) o;

        if (path != null ? !path.equals(fc.path) : fc.path != null) return false;
        if (lastmodified != null ? !lastmodified.equals(fc.lastmodified) : fc.lastmodified != null) return false;
        return md5 != null ? md5.equals(fc.md5) : fc.md5 == null;
    }

    @Override
    public int hashCode() {
    
    
        int result = path != null ? path.hashCode() : 0;
        result = 31 * result + (lastmodified != null ? lastmodified.hashCode() : 0);
        result = 31 * result + (md5 != null ? md5.hashCode() : 0);
        return result;
    }
}

私のエクスポートエクセル

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class MyExportExcel {
    
    

	private HSSFWorkbook hssfWorkbook;
	private HSSFSheet sheet;

	/**
	 * @return the hssfWorkbook
	 */
	public HSSFWorkbook getHssfWorkbook() {
    
    
		return hssfWorkbook;
	}

	/**
	 * @return the sheet
	 */
	public HSSFSheet getSheet() {
    
    
		return sheet;
	}

	/**
	 * @param sheet
	 *            the sheet to set
	 */
	public void setSheet(HSSFSheet sheet) {
    
    
		this.sheet = sheet;
	}

	/**
	 * @param hssfWorkbook
	 *            the hssfWorkbook to set
	 */
	public void setHssfWorkbook(HSSFWorkbook hssfWorkbook) {
    
    
		this.hssfWorkbook = hssfWorkbook;
	}

	/**
	 * 
	 * @Description:设置标题
	 * @return void 返回类型
	 */
	@SuppressWarnings("deprecation")
	public void setExcelTitle(String title, int colSum) {
    
    
		this.sheet = hssfWorkbook.createSheet(title);// 创建Excel工作表对象
		// 设置列宽
		for (int i = 0; i <= colSum; i++) {
    
    
			sheet.setColumnWidth((short) i, (short) 7250);
		}
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();

		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐
		cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐
		cellStyle.setWrapText(true);// 指定单元格自动换行

		// 设置单元格背景色
		cellStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

		// 设置单元格字体
		HSSFFont font = hssfWorkbook.createFont();
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		font.setFontName("宋体");
		font.setFontHeight((short) 300);
		cellStyle.setFont(font);

		// cellStyle.setBottomBorderColor(HSSFColor.GREEN.index); // 设置单元格的边框颜色.
		// cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// cellStyle.setLeftBorderColor(HSSFColor.GREEN.index);
		// cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// cellStyle.setRightBorderColor(HSSFColor.GREEN.index);
		// cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// cellStyle.setTopBorderColor(HSSFColor.GREEN.index);

		HSSFRow row = sheet.createRow(0);
		// 设置第一行
		HSSFCell cell = row.createCell(0);
		// 设置行宽
		row.setHeight((short) 600);
		// 定义单元格为字符串类型
		cell.setCellType(HSSFCell.ENCODING_UTF_16);

		cell.setCellValue(new HSSFRichTextString(title));

		// 指定合并区域
		sheet.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, (short) colSum));
		cell.setCellStyle(cellStyle);

	}

	/**
	 * 
	 * @Description:没有数据时excel
	 * @return void 返回类型
	 */
	public void setNullData(int colSum) {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();

		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐
		cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐

		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);

		HSSFRow row = sheet.createRow(2);
		for (int i = 0; i <= colSum; i++) {
    
    
			HSSFCell cell2 = row.createCell(i);
			cell2.setCellStyle(cellStyle);
		}
		// 设置第一行
		HSSFCell cell = row.createCell(0);
		// 设置行宽
		row.setHeight((short) 600);
		// 定义单元格为字符串类型
		cell.setCellType(HSSFCell.ENCODING_UTF_16);

		cell.setCellValue(new HSSFRichTextString("没有数据"));

		// 指定合并区域
		sheet.addMergedRegion(new CellRangeAddress((short) 2, (short) 0, 2, (short) colSum));
		cell.setCellStyle(cellStyle);
	}

	/**
	 * 
	 * @Description: 设置列名
	 * @return void 返回类型
	 */
	public void setNormalTwoRow(List<String> columHeader) {
    
    
		HSSFRow row1 = sheet.createRow(1);
		row1.setHeight((short) 400);

		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐
		cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐
		// HSSFCell cell3 = null;

		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);

		HSSFFont font = hssfWorkbook.createFont();
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		cellStyle.setFont(font);
		for (int i = 0; i < columHeader.size(); i++) {
    
    
			HSSFCell cell3 = row1.createCell(i);

			cell3.setCellType(HSSFCell.ENCODING_UTF_16);
			cell3.setCellStyle(cellStyle);
			cell3.setCellValue(new HSSFRichTextString(columHeader.get(i)));
		}
	}

	/**
	 * 根据方法调用顺序存入excel
	 * 
	 * @param data
	 *            包含泛型的list
	 * @param method
	 *            方法名
	 */
	public void setExcelData(List<?> data, List<String> method) {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);

		try {
    
    
			for (int j = 0; j < data.size(); j++) {
    
    
				HSSFRow row = sheet.createRow(2 + j);
				// System.out.println(data.get(j));
				Class<?> clazz = data.get(j).getClass();
				for (int i = 0; i < method.size(); i++) {
    
    
					HSSFCell cell = row.createCell(i);
					cell.setCellType(HSSFCell.ENCODING_UTF_16);
					cell.setCellStyle(cellStyle);
					java.lang.reflect.Method m = clazz.getMethod(method.get(i));
					if (m.invoke(data.get(j)) != null) {
    
    
						cell.setCellValue(m.invoke(data.get(j)).toString());
					} else {
    
    
						cell.setCellValue("");
					}
				}
			}
		} catch (NoSuchMethodException e) {
    
    
			e.printStackTrace();
		} catch (SecurityException e) {
    
    
			e.printStackTrace();
		} catch (IllegalAccessException e) {
    
    
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
    
    
			e.printStackTrace();
		} catch (InvocationTargetException e) {
    
    
			e.printStackTrace();
		}
	}

	/**
	 * 给Excel单元格绑定数据
	 * 
	 * @param list
	 *            数据Data
	 * @param colname
	 *            字段名
	 * @throws IllegalAccessException
	 */
	public void setExcelData2(List<?> list, List<String> colname) throws IllegalAccessException {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
		for (int j = 0; j < list.size(); j++) {
    
    
			HSSFRow row = sheet.createRow(2 + j);
			// System.out.println(list.get(j).toString());
			Map<String, Object> map;
			//如果传过来的数据类型是一个hashmap
			if(list.get(j).getClass().equals(HashMap.class))
			{
    
    
				map = (Map<String, Object>)list.get(j);
				//如果传过来的数据类型是一个实体类
			}else {
    
    
				map = objectToMap(list.get(j));
				System.out.println(map.toString());
			}
			System.out.println(map.toString());
			for (int i = 0; i < colname.size(); i++) {
    
    
				HSSFCell cell = row.createCell(i);
				cell.setCellType(HSSFCell.ENCODING_UTF_16);
				cell.setCellStyle(cellStyle);
				Object object = map.get(colname.get(i));

				if (object == null) {
    
    
					cell.setCellValue("");
				} else {
    
    
					cell.setCellValue(new HSSFRichTextString(object.toString()));
				}
			}
		}
	}

	/**
	 * 给Excel单元格绑定数据
	 * 
	 * @param list
	 *            数据Data
	 * @param colname
	 *            字段名
	 * @param startnum
	 *            起始位置
	 * @throws IllegalAccessException
	 */
	public void setExcelData2(List<?> list, List<String> colname, int startnum) throws IllegalAccessException {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
		for (int j = startnum; j < list.size(); j++) {
    
    
			HSSFRow row = sheet.createRow(2 + j);
			// System.out.println(list.get(j).toString());
			Map<String, Object> map = objectToMap(list.get(j));
			for (int i = 0; i < colname.size(); i++) {
    
    
				HSSFCell cell = row.createCell(i);
				cell.setCellType(HSSFCell.ENCODING_UTF_16);
				cell.setCellStyle(cellStyle);
				Object object = map.get(colname.get(i));

				if (object == null) {
    
    
					cell.setCellValue("");
				} else {
    
    
					cell.setCellValue(new HSSFRichTextString(object.toString()));
				}
			}
		}
	}

	/**
	 * 给Excel单元格绑定数据
	 * 
	 * @param list
	 *            数据Data
	 * @param colname
	 *            字段名
	 * @param change
	 *            起始位置
	 * @throws IllegalAccessException
	 */
	public void setExcelData2(List<?> list, List<String> colname, Map<String, Map<String, String>> change)
			throws IllegalAccessException {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
		for (int j = 0; j < list.size(); j++) {
    
    
			HSSFRow row = sheet.createRow(2 + j);
			// System.out.println(list.get(j).toString());
			Map<String, Object> map = objectToMap(list.get(j));
			for (int i = 0; i < colname.size(); i++) {
    
    
				HSSFCell cell = row.createCell(i);
				cell.setCellType(HSSFCell.ENCODING_UTF_16);
				cell.setCellStyle(cellStyle);
				Object object = map.get(colname.get(i));

				if (object == null) {
    
    
					cell.setCellValue("");
				} else {
    
    
					for (Entry<String, Map<String, String>> eny : change.entrySet()) {
    
    
						String fname = eny.getKey();
						Map<String, String> fval = eny.getValue();
						if (fname.equals(colname.get(i))) {
    
    
							cell.setCellValue(new HSSFRichTextString(fval.get(object.toString())));
						} else {
    
    
							cell.setCellValue(new HSSFRichTextString(object.toString()));
						}
					}
					// if (change.get(colname.get(i)) != null) {
    
    
					// Map<String,String> val= change.get(colname.get(i));
					// cell.setCellValue(new
					// HSSFRichTextString(val.get(object.toString())));
					// } else {
    
    
					// cell.setCellValue(new
					// HSSFRichTextString(object.toString()));
					// }
				}
			}
		}
	}
	
	
	/**
	 * @param list
	 *      list本身就是map
	 * @param colname
	 * 			列名
	 * @throws IllegalAccessException
	 */
	public void setExcelData3(List<?> list, List<String> colname) throws IllegalAccessException {
    
    
		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.
		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
		for (int j = 0; j < list.size(); j++) {
    
    
			HSSFRow row = sheet.createRow(2 + j);
			// System.out.println(list.get(j).toString());
			Map<String, String> map = (Map<String, String>) list.get(j);
			System.out.println(map.toString());
			for (int i = 0; i < colname.size(); i++) {
    
    
				HSSFCell cell = row.createCell(i);
				cell.setCellType(HSSFCell.ENCODING_UTF_16);
				cell.setCellStyle(cellStyle);
				Object object = map.get(colname.get(i));

				if (object == null) {
    
    
					cell.setCellValue("");
				} else {
    
    
					cell.setCellValue(new HSSFRichTextString(object.toString()));
				}
			}
		}
	}

	/**
	 * Object转Map(包含父类的属性)
	 * 
	 * @param obj
	 * @return
	 */
	public static Map<String, Object> objectToMap(Object obj) {
    
    
		Map<String, Object> reMap = new HashMap<String, Object>();
		if (obj == null)
			return null;
		try {
    
    
			Class<?> objClass = obj.getClass();
			while (objClass != null) {
    
    
				Field[] fields = objClass.getDeclaredFields();
				for (int i = 0; i < fields.length; i++) {
    
    
					try {
    
    
						Field f = objClass.getDeclaredField(fields[i].getName());
						f.setAccessible(true);
						Object o = f.get(obj);
						reMap.put(fields[i].getName(), o);
					} catch (NoSuchFieldException e) {
    
    
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
    
    
						e.printStackTrace();
					} catch (IllegalAccessException e) {
    
    
						e.printStackTrace();
					}
				}
				objClass = objClass.getSuperclass();
			}
		} catch (SecurityException e) {
    
    
			e.printStackTrace();
		}
		return reMap;
	}

	
}

回答フォーム

import java.io.Serializable;

/**
* 这个类是根据layui接收数据的格式来定义的,
* private Object data; 存放的JSON数据
* private String code; , layui规定的格式, 需要在JSON数据前面有一个code字符创的状态码  code:0  , 我们这里固定返回200 , 前端会自动检验并且转换为0
* private message message; 这里是返回的信息, 在JSON数据的后面 , 成功就是SUCCESS , 失败就是FAIL, 这是layui解析表格固定JSON字符串的格式
* private Integer total; 这个属性是layui数据表格在展示分页数据的时候 , 需要的一个参数.我们后台把数据分页后,返回这个参数.
*
*/
public class ResponseForm implements Serializable {
    
    
	//返回的数据
	private Object data;
	//返回的状态码,200表示成功,400表示失败
	private String code;
	//返回的信息,成功失败
	private message message;
	//分页总数
	private Integer total;

	//每页数据量的参数名,默认:limit
	private Integer limit;

	public Integer getLimit() {
    
    
		return limit;
	}

	public void setLimit(Integer limit) {
    
    
		this.limit = limit;
	}

	public enum message {
    
    
		SUCCESS,
		FAIL
	}

	public ResponseForm() {
    
    
	}

	public ResponseForm(Object data, String code, ResponseForm.message message, Integer total) {
    
    
		this.data = data;
		this.code = code;
		this.message = message;
		this.total = total;
	}

	public Object getData() {
    
    
		return data;
	}

	public void setData(Object data) {
    
    
		this.data = data;
	}

	public String getCode() {
    
    
		return code;
	}

	public void setCode(String code) {
    
    
		this.code = code;
	}

	public ResponseForm.message getMessage() {
    
    
		return message;
	}

	public void setMessage(ResponseForm.message message) {
    
    
		this.message = message;
	}

	public Integer getTotal() {
    
    
		return total;
	}

	public void setTotal(Integer total) {
    
    
		this.total = total;
	}
}

サービス


import com.alibaba.fastjson.JSONObject;

public interface FileComparesService {
    
    
    void fileComparesimple(String firstpath, String secondpath);

    Integer initPercentage(String firstpath, String secondpath);

    JSONObject fileComparesimplePercentage();

    JSONObject getfileCompares();
}

サービスインプル



import com.alibaba.fastjson.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class FileComparesServiceImpl implements FileComparesService {
    
    
    private static final Logger logger = Logger.getLogger(FileComparesServiceImpl.class);
    public static String syncCurrentName1 = null; // 进度条name
    public static String percentage1; // 进度条百分比
    public static Integer percentagesum1 = null; // 文件总数
    public static int[] countfile;//当前文件个数

    public static final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();//全局静态变量
    private List listoneNot1 = new ArrayList<Fc>(); //存放数据一缺失的数据
    private List listoneNot2 = new ArrayList<Fc>(); //存放数据二缺失的数据
    private List listoneNot3 = new ArrayList<Fc>(); //存放数据二缺失的数据

    public static boolean flag;
    private Boolean[] scanStop = new Boolean[1]; // 检测停止标识


    @Override
    public void fileComparesimple(String firstpath, String secondpath) {
    
    
        long startTime = System.currentTimeMillis();

        // 读取服务器cpu核数
        int cpuCount = Util.getCPUnum();
        cpuCount = cpuCount > 10 ? 10 : 5;
//        int cpuCount = 4;
        countfile = new int[]{
    
    0};

//        String dirName1 = "C:\\Users\\taiyu\\Desktop\\file2\\10w";
        String dirName1 = firstpath;
        File root1 = new File(dirName1);

        String dirName2 = secondpath;
        File root2 = new File(dirName2);

        listoneNot1 = new ArrayList<Fc>();
        listoneNot2 = new ArrayList<Fc>();
        listoneNot3 = new ArrayList<Fc>();
        scanStop[0] = true;
        List list = new ArrayList();
        list.add(dirName1);
        list.add(dirName2);

        logger.info("分配线程开始...");
        CountDownLatch latchs = new CountDownLatch(cpuCount + 1);
        ExecutorService exec = Executors.newCachedThreadPool();

        // 读取文件线程
        final ReadFile2 trFile1 = new ReadFile2(
                latchs, null, list,
                dirName1, dirName2, scanStop);
        logger.info("读取文件线程启动...");
        exec.execute(new Thread() {
    
    
            @Override
            public void run() {
    
    
                trFile1.readFile();
            }
        });

        for (int i = 0; i < cpuCount; i++) {
    
    
            final CompareThreadUtil thDao = new CompareThreadUtil(
                    latchs, null, list, listoneNot1,
                    listoneNot2, listoneNot3, root1,
                    root2, dirName1, dirName2, trFile1, scanStop);
            System.out.println("检测线程" + i + " 启动...");
            final int currentID = i;
            exec.execute(new Thread() {
    
    
                @Override
                public void run() {
    
    
                    thDao.addFileLevelAfter(currentID, percentagesum1, countfile);
                }
            });
        }
        try {
    
    
            exec.shutdown();
            latchs.await();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        //结束时间
        long endTime1 = System.currentTimeMillis();
        //打印
        System.out.println("对比运行时间:" + (double) (endTime1 - startTime) / 1000 + "s");
        //打印数据1缺失数据
        if (listoneNot1.size() > 0) {
    
    
            logger.info("数据1删除的文件如下");
            for (int i = 0; i < listoneNot1.size(); i++) {
    
    
                logger.info(((Fc) listoneNot1.get(0)).getPath());
            }
        } else {
    
    
            logger.info("数据1无删除的文件...");
        }

        //打印数据2缺失数据
        if (listoneNot2.size() > 0) {
    
    
            logger.info("数据2删除的文件如下");
            for (int i = 0; i < listoneNot2.size(); i++) {
    
    
                logger.info(((Fc) listoneNot2.get(i)).getPath());
            }
        } else {
    
    
            logger.info("数据2无删除文件");
        }
        //打印数据3缺失数据
        if (listoneNot3.size() > 0) {
    
    
            logger.info("两数据源之间发生修改的文件如下");
            for (int i = 0; i < listoneNot3.size(); i++) {
    
    
                logger.info(((Fc) listoneNot3.get(i)).getPath());
            }
        } else {
    
    
            logger.info("两数据源之间无发生修改的文件");
        }
        //结束时间
        long endTime = System.currentTimeMillis();
        //打印
        System.out.println("程序运行时间:" + (double) (endTime - startTime) / 1000 + "s");


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("数据源1发生删除的文件", listoneNot1);
        jsonObject.put("数据源2发生删除的文件", listoneNot2);
        jsonObject.put("两数据源对比发生修改的文件", listoneNot3);
        flag = true;
        jsonObject.put("flag", flag);
    }

    @Override
    public Integer initPercentage(String firstpath, String secondpath) {
    
    
        flag = false;
        percentagesum1 = 0;
        percentage1 = "";
        syncCurrentName1 = "";
        readFileInfo(new File(firstpath));
        readFileInfo(new File(secondpath));
        return percentagesum1;
    }

    @Override
    public JSONObject fileComparesimplePercentage() {
    
    
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("百分比", percentage1);
        jsonObject.put("当前进行到的文件", syncCurrentName1);
        jsonObject.put("flag", flag);//为true时可以取结果

        return jsonObject;
    }

    @Override
    public JSONObject getfileCompares() {
    
    

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("数据源1发生删除的文件", listoneNot1);
        jsonObject.put("数据源2发生删除的文件", listoneNot2);
        jsonObject.put("两数据源对比发生修改的文件", listoneNot3);
        return jsonObject;
    }


    private void readFileInfo(File root) {
    
    
        if (root.exists()) {
    
    
            if (root.isDirectory()) {
    
    
                File[] files = root.listFiles();
                if (files != null) {
    
    
                    for (int i = 0; i < files.length; i++) {
    
    

                        if (files[i].isFile()) {
    
    
                            percentagesum1++;
                        } else if (files[i].isDirectory()) {
    
    
                            readFileInfo(files[i]);
                        }
                        files[i] = null;
                    }
                }
                files = null;
            } else if (root.isFile()) {
    
    
                percentagesum1++;
            }
        }
    }
}

helloWorldアプリケーション

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication( exclude= DataSourceAutoConfiguration.class)
public class helloWorldApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(helloWorldApplication.class, args);
    }
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_54765221/article/details/125786853