最近工作中有个功能,是导出一批体量在几十万的照片文件,导出的结构是在不同文件夹下。客户让确定一下导出的数据和库中统计的数据是不是一致的,文件命名规范与否,这下手动去比对是不可能了,作为程序员,就只能上脚本了,首先捋一下脚本要做到的事:
1.给出一个指定的路径,能去这个路径下面自动的统计有多少文件夹,文件夹下有多少文件
2.检测一下每个文件的名称是否规范,并记录不规范的文件名
3.最后能将检查结果以Excel的形式导出
最后一条涉及到导出 Excel,这个不是本篇的主要目的,只上代码,着重梳理如何统计指定路径下的文件与文件夹的内容,上代码:
- File folder = new File("E:\\formalPhoto");
- //获取该路径下文件夹中的文件或者文件夹列表
- File[] list = folder.listFiles();
- Map
cout = new HashMap<>(); - List
other = new ArrayList<>(); - String folderName = "";
- //城市文件夹数量
- int kaodianNum = 0;
- //省份文件夹数量
- int kaoquNum = 0;
- //记录所有照片文件数量
- int kaoshengNum = 0;
- //开始循环改文件夹下的内容列表
- for (File file : list) {
- //判断省份文件夹
- if (file.isDirectory()) {
- //得到地市文件夹的list
- File[] files = file.listFiles();
- //地市文件夹不为空
- if (files != null && ArrayUtils.isNotEmpty(files)) {
- //循环地市list,得到每个地市文件夹
- for (File filePhoto : files) {
- //判断地市文件夹是不是文件夹
- if (filePhoto.isDirectory()) {
- //是文件夹,记录地市的名称,这里业务需要做了截取,直接获取也可以用
- folderName = filePhoto.getName().substring(0, 4);
- //初始化当前文件夹中照片文件数量
- int fileCount = 0;
- //得到照片list
- File[] filePhotos = filePhoto.listFiles();
- //判断照片内容不为空
- if (filePhotos != null && ArrayUtils.isNotEmpty(filePhotos)) {
- for (File filePho : filePhotos) {
- if (filePho.isFile()) {
- //文件名称中包含"未导出照片"的不是照片,做判断跳过
- if (!filePho.getName().contains("未导出照片")) {
- //是照片文件,获取文件名
- String no = filePho.getName().replace(".jpg", "");
- //对照片名称做业务要求的检验,没有需要可以不写
- // boolean mismatchIdCard = StringConstant.ONE.equals("1") && RegexUtil.match(RegexpConstant.IDCARD, no);
- // if (mismatchIdCard) {
- // //是照片文件,文件数计数
- // fileCount++;
- // } else {
- // //是照片文件,文件数计数
- // other.add(no);
- //照片文件累加
- fileCount++;
- // }
- //总文件数累加
- kaoshengNum++;
- }
- }
- //记录当前城市文件夹名称与对应的照片文件数量
- cout.put(folderName, String.valueOf(fileCount));
- }
- }
- }
- //城市文件夹数量累加
- kaodianNum++;
- }
-
- }
- }
- //省份文件夹数量累加
- kaoquNum++;
- }
核心方法拆开解析:

.listFiles():获取文件夹下的所有内容,不论文件还是文件夹

.isDirectory():判断是不是文件夹,返回布尔类型

.getName():获取当前对象的名称,文件或者文件夹名称
其实上面的代码主要就是这几个方法的循环嵌套,没什么复杂。
我这里直接上代码,不对Excel的代码做过多描述,也不复杂,直接能用:
- String hallFilePath = "E:\\formalPhoto";
- File filePath = new File(hallFilePath);
- if (!filePath.exists()) {
- filePath.mkdirs();
- }
- //Excel表名称
- String examPath = hallFilePath + File.separator + "统计信息表.xlsx";
- // 创建excel工作簿
- SXSSFWorkbook wb = new SXSSFWorkbook(getXSSFWorkbook(examPath), 1000);
- // 获取第一个sheet(页)
- SXSSFSheet sheet = wb.getSheetAt(0);
- // 创建第一行
- SXSSFRow row = sheet.createRow(0);
- //设置列名
- row.createCell(0).setCellValue("城市代码");
- row.createCell(1).setCellValue("人数");
- row.createCell(2).setCellValue("简称");
- Set set = cout.entrySet();
- int i = 0;
- for (Object key : set) {
- ++i;
- Map.Entry entry = (Map.Entry) key;
- SXSSFRow rowRev = sheet.createRow(i + 1);
- // 在row行上创建一个方格
- rowRev.createCell(0).setCellValue(entry.getKey().toString());
- rowRev.createCell(1).setCellValue(entry.getValue().toString());
- rowRev.createCell(2).setCellValue(entry.getKey().toString().substring(0,2));
- }
- //生成Excel文件
- BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(examPath));
- wb.write(outputStream);
- outputStream.flush();
- wb.dispose();// 释放workbook所占用的所有windows资源
里面的getXSSFWorkbook()方法:
- /**
- * 先创建一个XSSFWorkbook对象
- *
- * @param filePath
- * @return
- */
- public static XSSFWorkbook getXSSFWorkbook(String filePath) {
- XSSFWorkbook workbook = null;
- BufferedOutputStream outputStream = null;
- try {
- File fileXlsxPath = new File(filePath);
- outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
- workbook = new XSSFWorkbook();
- workbook.createSheet("sheet1");
- workbook.write(outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return workbook;
- }
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
- public static void main(String[] args) throws IOException {
- numberOfFiles();
- }
-
- //计算指定路径下文件夹和文件数
- public static void numberOfFiles() throws IOException {
- File folder = new File("E:\\formalPhoto");
- //获取该路径下文件夹中的文件或者文件夹列表
- File[] list = folder.listFiles();
- Map
cout = new HashMap<>(); - List
other = new ArrayList<>(); - String folderName = "";
- int kaodianNum = 0;
- int kaoquNum = 0;
- int kaoshengNum = 0;
- //开始循环改文件夹下的内容列表
- for (File file : list) {
- //判断省份文件夹
- if (file.isDirectory()) {
- //得到地市文件夹的list
- File[] files = file.listFiles();
- //地市文件夹不为空
- if (files != null && ArrayUtils.isNotEmpty(files)) {
- //循环地市list,得到每个地市文件夹
- for (File filePhoto : files) {
- //判断地市文件夹是不是文件夹
- if (filePhoto.isDirectory()) {
- //是文件夹,记录地市的名称,这里业务需要做了截取,直接获取也可以用
- folderName = filePhoto.getName().substring(0, 4);
- //初始化照片文件数量
- int fileCount = 0;
- //得到照片list
- File[] filePhotos = filePhoto.listFiles();
- //判断照片内容不为空
- if (filePhotos != null && ArrayUtils.isNotEmpty(filePhotos)) {
- for (File filePho : filePhotos) {
- if (filePho.isFile()) {
- //文件名称中包含"未导出照片"的不是照片,做判断跳过
- if (!filePho.getName().contains("未导出照片")) {
- //是照片文件,获取文件名
- String no = filePho.getName().replace(".jpg", "");
- //对照片名称做业务要求的检验,没有需要可以不写
- // boolean mismatchIdCard = StringConstant.ONE.equals("1") && RegexUtil.match(RegexpConstant.IDCARD, no);
- // if (mismatchIdCard) {
- // //是照片文件,文件数计数
- // fileCount++;
- // } else {
- // //是照片文件,文件数计数
- // other.add(no);
- fileCount++;
- // }
- kaoshengNum++;
- }
- }
- cout.put(folderName, String.valueOf(fileCount));
- }
- }
- }
- kaodianNum++;
- }
-
- }
- }
- kaoquNum++;
- }
- String hallFilePath = "E:\\formalPhoto";
- File filePath = new File(hallFilePath);
- if (!filePath.exists()) {
- filePath.mkdirs();
- }
- //Excel表名称
- String examPath = hallFilePath + File.separator + "考生信息表.xlsx";
- // 创建excel工作簿
- SXSSFWorkbook wb = new SXSSFWorkbook(getXSSFWorkbook(examPath), 1000);
- // 获取第一个sheet(页)
- SXSSFSheet sheet = wb.getSheetAt(0);
- // 创建第一行
- SXSSFRow row = sheet.createRow(0);
- //设置列名
- row.createCell(0).setCellValue("地市代码");
- row.createCell(1).setCellValue("人数");
- row.createCell(2).setCellValue("简称");
- Set set = cout.entrySet();
- int i = 0;
- for (Object key : set) {
- ++i;
- Map.Entry entry = (Map.Entry) key;
- SXSSFRow rowRev = sheet.createRow(i + 1);
- // 在row行上创建一个方格
- rowRev.createCell(0).setCellValue(entry.getKey().toString());
- rowRev.createCell(1).setCellValue(entry.getValue().toString());
- rowRev.createCell(2).setCellValue(entry.getKey().toString().substring(0,2));
- }
- //生成Excel文件
- BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(examPath));
- wb.write(outputStream);
- outputStream.flush();
- wb.dispose();// 释放workbook所占用的所有windows资源
- System.out.println("照片信息核对:" + cout);
- System.out.println("----------------非身份证的号码:" + other);
- System.out.println("总考点数:" + kaodianNum);
- System.out.println("总考区数:" + kaoquNum);
- System.out.println("总考生数:" + kaoshengNum);
- }
-
-
- /**
- * 先创建一个XSSFWorkbook对象
- *
- * @param filePath
- * @return
- */
- public static XSSFWorkbook getXSSFWorkbook(String filePath) {
- XSSFWorkbook workbook = null;
- BufferedOutputStream outputStream = null;
- try {
- File fileXlsxPath = new File(filePath);
- outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
- workbook = new XSSFWorkbook();
- workbook.createSheet("sheet1");
- workbook.write(outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return workbook;
- }
如果不需要导出Excel,可以去掉那部分代码,直接在控制台打印想要的数据即可。
工作之余记录一下,算是日常工具方法的累计,欢迎各位指点。