• Java统计指定目录下文件夹数量和内部文件的数量并导出


    最近工作中有个功能,是导出一批体量在几十万的照片文件,导出的结构是在不同文件夹下。客户让确定一下导出的数据和库中统计的数据是不是一致的,文件命名规范与否,这下手动去比对是不可能了,作为程序员,就只能上脚本了,首先捋一下脚本要做到的事:

    1.给出一个指定的路径,能去这个路径下面自动的统计有多少文件夹,文件夹下有多少文件

    2.检测一下每个文件的名称是否规范,并记录不规范的文件名

    3.最后能将检查结果以Excel的形式导出

    最后一条涉及到导出 Excel,这个不是本篇的主要目的,只上代码,着重梳理如何统计指定路径下的文件与文件夹的内容,上代码:

    下面案例中要循环的结构为:指定路径---->省份文件夹------>城市文件夹------->照片

    1.统计指定路径下文件夹中内容的统计方法,具体逻辑见注释,很详细了:

    1. File folder = new File("E:\\formalPhoto");
    2. //获取该路径下文件夹中的文件或者文件夹列表
    3. File[] list = folder.listFiles();
    4. Map cout = new HashMap<>();
    5. List other = new ArrayList<>();
    6. String folderName = "";
    7. //城市文件夹数量
    8. int kaodianNum = 0;
    9. //省份文件夹数量
    10. int kaoquNum = 0;
    11. //记录所有照片文件数量
    12. int kaoshengNum = 0;
    13. //开始循环改文件夹下的内容列表
    14. for (File file : list) {
    15. //判断省份文件夹
    16. if (file.isDirectory()) {
    17. //得到地市文件夹的list
    18. File[] files = file.listFiles();
    19. //地市文件夹不为空
    20. if (files != null && ArrayUtils.isNotEmpty(files)) {
    21. //循环地市list,得到每个地市文件夹
    22. for (File filePhoto : files) {
    23. //判断地市文件夹是不是文件夹
    24. if (filePhoto.isDirectory()) {
    25. //是文件夹,记录地市的名称,这里业务需要做了截取,直接获取也可以用
    26. folderName = filePhoto.getName().substring(0, 4);
    27. //初始化当前文件夹中照片文件数量
    28. int fileCount = 0;
    29. //得到照片list
    30. File[] filePhotos = filePhoto.listFiles();
    31. //判断照片内容不为空
    32. if (filePhotos != null && ArrayUtils.isNotEmpty(filePhotos)) {
    33. for (File filePho : filePhotos) {
    34. if (filePho.isFile()) {
    35. //文件名称中包含"未导出照片"的不是照片,做判断跳过
    36. if (!filePho.getName().contains("未导出照片")) {
    37. //是照片文件,获取文件名
    38. String no = filePho.getName().replace(".jpg", "");
    39. //对照片名称做业务要求的检验,没有需要可以不写
    40. // boolean mismatchIdCard = StringConstant.ONE.equals("1") && RegexUtil.match(RegexpConstant.IDCARD, no);
    41. // if (mismatchIdCard) {
    42. // //是照片文件,文件数计数
    43. // fileCount++;
    44. // } else {
    45. // //是照片文件,文件数计数
    46. // other.add(no);
    47. //照片文件累加
    48. fileCount++;
    49. // }
    50. //总文件数累加
    51. kaoshengNum++;
    52. }
    53. }
    54. //记录当前城市文件夹名称与对应的照片文件数量
    55. cout.put(folderName, String.valueOf(fileCount));
    56. }
    57. }
    58. }
    59. //城市文件夹数量累加
    60. kaodianNum++;
    61. }
    62. }
    63. }
    64. //省份文件夹数量累加
    65. kaoquNum++;
    66. }

    核心方法拆开解析:

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

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

    .getName():获取当前对象的名称,文件或者文件夹名称

    其实上面的代码主要就是这几个方法的循环嵌套,没什么复杂。

    2.将循环得到的内容用Excel记录下来:

    我这里直接上代码,不对Excel的代码做过多描述,也不复杂,直接能用:

    1. String hallFilePath = "E:\\formalPhoto";
    2. File filePath = new File(hallFilePath);
    3. if (!filePath.exists()) {
    4. filePath.mkdirs();
    5. }
    6. //Excel表名称
    7. String examPath = hallFilePath + File.separator + "统计信息表.xlsx";
    8. // 创建excel工作簿
    9. SXSSFWorkbook wb = new SXSSFWorkbook(getXSSFWorkbook(examPath), 1000);
    10. // 获取第一个sheet(页)
    11. SXSSFSheet sheet = wb.getSheetAt(0);
    12. // 创建第一行
    13. SXSSFRow row = sheet.createRow(0);
    14. //设置列名
    15. row.createCell(0).setCellValue("城市代码");
    16. row.createCell(1).setCellValue("人数");
    17. row.createCell(2).setCellValue("简称");
    18. Set set = cout.entrySet();
    19. int i = 0;
    20. for (Object key : set) {
    21. ++i;
    22. Map.Entry entry = (Map.Entry) key;
    23. SXSSFRow rowRev = sheet.createRow(i + 1);
    24. // 在row行上创建一个方格
    25. rowRev.createCell(0).setCellValue(entry.getKey().toString());
    26. rowRev.createCell(1).setCellValue(entry.getValue().toString());
    27. rowRev.createCell(2).setCellValue(entry.getKey().toString().substring(0,2));
    28. }
    29. //生成Excel文件
    30. BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(examPath));
    31. wb.write(outputStream);
    32. outputStream.flush();
    33. wb.dispose();// 释放workbook所占用的所有windows资源

     里面的getXSSFWorkbook()方法:

    1. /**
    2. * 先创建一个XSSFWorkbook对象
    3. *
    4. * @param filePath
    5. * @return
    6. */
    7. public static XSSFWorkbook getXSSFWorkbook(String filePath) {
    8. XSSFWorkbook workbook = null;
    9. BufferedOutputStream outputStream = null;
    10. try {
    11. File fileXlsxPath = new File(filePath);
    12. outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
    13. workbook = new XSSFWorkbook();
    14. workbook.createSheet("sheet1");
    15. workbook.write(outputStream);
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. } finally {
    19. if (outputStream != null) {
    20. try {
    21. outputStream.close();
    22. } catch (IOException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }
    27. return workbook;
    28. }

     3.完整代码如下,不出意外jar包都可引入,直接复制可用:

    1. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    2. public static void main(String[] args) throws IOException {
    3. numberOfFiles();
    4. }
    5. //计算指定路径下文件夹和文件数
    6. public static void numberOfFiles() throws IOException {
    7. File folder = new File("E:\\formalPhoto");
    8. //获取该路径下文件夹中的文件或者文件夹列表
    9. File[] list = folder.listFiles();
    10. Map cout = new HashMap<>();
    11. List other = new ArrayList<>();
    12. String folderName = "";
    13. int kaodianNum = 0;
    14. int kaoquNum = 0;
    15. int kaoshengNum = 0;
    16. //开始循环改文件夹下的内容列表
    17. for (File file : list) {
    18. //判断省份文件夹
    19. if (file.isDirectory()) {
    20. //得到地市文件夹的list
    21. File[] files = file.listFiles();
    22. //地市文件夹不为空
    23. if (files != null && ArrayUtils.isNotEmpty(files)) {
    24. //循环地市list,得到每个地市文件夹
    25. for (File filePhoto : files) {
    26. //判断地市文件夹是不是文件夹
    27. if (filePhoto.isDirectory()) {
    28. //是文件夹,记录地市的名称,这里业务需要做了截取,直接获取也可以用
    29. folderName = filePhoto.getName().substring(0, 4);
    30. //初始化照片文件数量
    31. int fileCount = 0;
    32. //得到照片list
    33. File[] filePhotos = filePhoto.listFiles();
    34. //判断照片内容不为空
    35. if (filePhotos != null && ArrayUtils.isNotEmpty(filePhotos)) {
    36. for (File filePho : filePhotos) {
    37. if (filePho.isFile()) {
    38. //文件名称中包含"未导出照片"的不是照片,做判断跳过
    39. if (!filePho.getName().contains("未导出照片")) {
    40. //是照片文件,获取文件名
    41. String no = filePho.getName().replace(".jpg", "");
    42. //对照片名称做业务要求的检验,没有需要可以不写
    43. // boolean mismatchIdCard = StringConstant.ONE.equals("1") && RegexUtil.match(RegexpConstant.IDCARD, no);
    44. // if (mismatchIdCard) {
    45. // //是照片文件,文件数计数
    46. // fileCount++;
    47. // } else {
    48. // //是照片文件,文件数计数
    49. // other.add(no);
    50. fileCount++;
    51. // }
    52. kaoshengNum++;
    53. }
    54. }
    55. cout.put(folderName, String.valueOf(fileCount));
    56. }
    57. }
    58. }
    59. kaodianNum++;
    60. }
    61. }
    62. }
    63. kaoquNum++;
    64. }
    65. String hallFilePath = "E:\\formalPhoto";
    66. File filePath = new File(hallFilePath);
    67. if (!filePath.exists()) {
    68. filePath.mkdirs();
    69. }
    70. //Excel表名称
    71. String examPath = hallFilePath + File.separator + "考生信息表.xlsx";
    72. // 创建excel工作簿
    73. SXSSFWorkbook wb = new SXSSFWorkbook(getXSSFWorkbook(examPath), 1000);
    74. // 获取第一个sheet(页)
    75. SXSSFSheet sheet = wb.getSheetAt(0);
    76. // 创建第一行
    77. SXSSFRow row = sheet.createRow(0);
    78. //设置列名
    79. row.createCell(0).setCellValue("地市代码");
    80. row.createCell(1).setCellValue("人数");
    81. row.createCell(2).setCellValue("简称");
    82. Set set = cout.entrySet();
    83. int i = 0;
    84. for (Object key : set) {
    85. ++i;
    86. Map.Entry entry = (Map.Entry) key;
    87. SXSSFRow rowRev = sheet.createRow(i + 1);
    88. // 在row行上创建一个方格
    89. rowRev.createCell(0).setCellValue(entry.getKey().toString());
    90. rowRev.createCell(1).setCellValue(entry.getValue().toString());
    91. rowRev.createCell(2).setCellValue(entry.getKey().toString().substring(0,2));
    92. }
    93. //生成Excel文件
    94. BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(examPath));
    95. wb.write(outputStream);
    96. outputStream.flush();
    97. wb.dispose();// 释放workbook所占用的所有windows资源
    98. System.out.println("照片信息核对:" + cout);
    99. System.out.println("----------------非身份证的号码:" + other);
    100. System.out.println("总考点数:" + kaodianNum);
    101. System.out.println("总考区数:" + kaoquNum);
    102. System.out.println("总考生数:" + kaoshengNum);
    103. }
    104. /**
    105. * 先创建一个XSSFWorkbook对象
    106. *
    107. * @param filePath
    108. * @return
    109. */
    110. public static XSSFWorkbook getXSSFWorkbook(String filePath) {
    111. XSSFWorkbook workbook = null;
    112. BufferedOutputStream outputStream = null;
    113. try {
    114. File fileXlsxPath = new File(filePath);
    115. outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
    116. workbook = new XSSFWorkbook();
    117. workbook.createSheet("sheet1");
    118. workbook.write(outputStream);
    119. } catch (Exception e) {
    120. e.printStackTrace();
    121. } finally {
    122. if (outputStream != null) {
    123. try {
    124. outputStream.close();
    125. } catch (IOException e) {
    126. e.printStackTrace();
    127. }
    128. }
    129. }
    130. return workbook;
    131. }

    如果不需要导出Excel,可以去掉那部分代码,直接在控制台打印想要的数据即可。

    工作之余记录一下,算是日常工具方法的累计,欢迎各位指点。

  • 相关阅读:
    有没有手机能做的线上兼职副业?
    数据特征选择 | Lasso特征选择(Python)
    使用Alight Motion进行编程:创建动态效果的简易指南
    第160场直播带货数据分享
    Vue 搭配 Spring MVC 创建一个 web 项目
    让gorm代码飞起来,gorm+gmodeltool生成entity,让实体类代码更轻松。
    naive-ui的n-data-table标签奇特bug记录
    Apple开发如何在设备中切换IAP(内购)沙盒测试账户?
    开发者模式:单例模式
    【C语言】Windows下的C语言线程编程详解
  • 原文地址:https://blog.csdn.net/httpmc2018/article/details/126951582