2026-04-09 星期四 2306 对照片和视频文件名,程序追加日期,直观看
2026-04-09 星期四 2306 原本是想着,手机导出的照片跟苹果拍摄的图片,文件名没有直观的拍摄日期,所以想着对文件名重新命名,加上日期,方便直观看,手动也试着加过,太累了,就用程序追加,直观如下

java
"H:\DevelopInstall\JetBrains\IntelliJ IDEA 2019.2.3\jbr\bin\java.exe" "-javaagent:H:\DevelopInstall\JetBrains\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=52257:H:\DevelopInstall\JetBrains\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath H:\JavaWorkSpace\2026\20260406_addDataToPhotoFileName\target\classes;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-starter-web\2.5.4\spring-boot-starter-web-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-starter\2.5.4\spring-boot-starter-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot\2.5.4\spring-boot-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-autoconfigure\2.5.4\spring-boot-autoconfigure-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-starter-logging\2.5.4\spring-boot-starter-logging-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\ch\qos\logback\logback-classic\1.2.5\logback-classic-1.2.5.jar;H:\Maven\aLiBaBa_repo_repository\ch\qos\logback\logback-core\1.2.5\logback-core-1.2.5.jar;H:\Maven\aLiBaBa_repo_repository\org\slf4j\slf4j-api\1.7.31\slf4j-api-1.7.31.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;H:\Maven\aLiBaBa_repo_repository\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;H:\Maven\aLiBaBa_repo_repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-core\5.3.9\spring-core-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-jcl\5.3.9\spring-jcl-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\yaml\snakeyaml\1.28\snakeyaml-1.28.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-starter-json\2.5.4\spring-boot-starter-json-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\core\jackson-databind\2.12.4\jackson-databind-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\core\jackson-annotations\2.12.4\jackson-annotations-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\core\jackson-core\2.12.4\jackson-core-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.12.4\jackson-datatype-jdk8-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.12.4\jackson-datatype-jsr310-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.12.4\jackson-module-parameter-names-2.12.4.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\boot\spring-boot-starter-tomcat\2.5.4\spring-boot-starter-tomcat-2.5.4.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.52\tomcat-embed-core-9.0.52.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.52\tomcat-embed-el-9.0.52.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.52\tomcat-embed-websocket-9.0.52.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-web\5.3.9\spring-web-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-beans\5.3.9\spring-beans-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-webmvc\5.3.9\spring-webmvc-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-aop\5.3.9\spring-aop-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-context\5.3.9\spring-context-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\org\springframework\spring-expression\5.3.9\spring-expression-5.3.9.jar;H:\Maven\aLiBaBa_repo_repository\com\drewnoakes\metadata-extractor\2.6.2\metadata-extractor-2.6.2.jar;H:\Maven\aLiBaBa_repo_repository\com\adobe\xmp\xmpcore\5.1.2\xmpcore-5.1.2.jar;H:\Maven\aLiBaBa_repo_repository\xerces\xercesImpl\2.8.1\xercesImpl-2.8.1.jar;H:\Maven\aLiBaBa_repo_repository\xml-apis\xml-apis\1.3.03\xml-apis-1.3.03.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\commons\commons-imaging\1.0-alpha2\commons-imaging-1.0-alpha2.jar;H:\Maven\aLiBaBa_repo_repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\logging\log4j\log4j-api\2.13.0\log4j-api-2.13.0.jar;H:\Maven\aLiBaBa_repo_repository\org\apache\logging\log4j\log4j-core\2.13.0\log4j-core-2.13.0.jar com.enan.common.util.ReadFileUtil
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: H:\Test_Test 是一个文件夹。
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2022-03-14 095638_1.jpg,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2023-04-23 103812_IMG_1695.MOV,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2023-04-23 112300_IMG_1706.MOV,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2023-07-18 095535_1.mp4,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2024-05-30 172245_1717060923716 (2).mp4,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2024-05-30 172245_1717060923716.mp4,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2024-06-28 205036_sd1719579037_2.mp4,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2024-07-09 152831_-882421106.mp4,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2025-04-09 131123_112233_IMG_20250409_131122.jpg,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2026-04-06 155402_IMG_6076.png,是以指定年份开头的,不需要重新命名
4月 09, 2026 11:12:36 下午 com.enan.common.util.ReadFileUtil readFileCreateDateAndAddDate
信息: 文件名:2026-04-06 155412_2.png,是以指定年份开头的,不需要重新命名
Process finished with exit code 0
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>enAn</groupId>
<artifactId>com.en.an</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<logging.log4j.version>2.13.0</logging.log4j.version>
</properties>
<!-- 导包 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.4</version> <!-- 确保使用适合你项目的版本 -->
</dependency>
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-imaging</artifactId>
<version>1.0-alpha2</version> <!-- 请检查最新版本 -->
</dependency>
<!-- Apache Commons IO实现 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<!-- Log4j2日志记录框架 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
</dependencies>
</project>
xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 参考:https://cloud.tencent.com/developer/article/2051336
日期:2026-04-09 星期四 1712
-->
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
-->
<!-- 控制台只输出debug及以上级别的信息 -->
<ThresholdFilter level="debug" />
<!-- 输出日志的格式 -->
<!-- 4月 09, 2026 10:49:19 下午 ReadFileUtil readFileCreateDateAndAddDate
<PatternLayout pattern="%d %-5level %class{36} %L %M - %msg%xEx%n"/>
-->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %class{36} %L %M - %msg%xEx%n"/>
</console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
<File name="log" fileName="log/test.log" append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.springframework" level="INFO"></logger>
<logger name="org.mybatis" level="INFO"></logger>
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
java
package com.enan.common.util;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;
public class ReadFileUtil {
private static final Logger log = Logger.getLogger(String.valueOf(ReadFileUtil.class));
public static void reNameFile(String oldFilePath,String newFilePath){
File oldFile = new File(oldFilePath);
File newFile = new File(newFilePath);
String oldFileName = "";
String msg = "";
try {
if (!oldFile.exists()) {
//FileUtils.touch(oldFile);
msg = "异常:源目标文件不存在: [" + oldFile.getName() + "],源路径:[" + oldFilePath + "]";
throw new Exception(msg);
}
if (newFile.exists()) {
msg = "异常:新目标文件已存在: [" + newFile.getName() + "],源路径:[" + newFilePath + "]";
throw new Exception(msg);
}
oldFileName = oldFile.getName();
FileUtils.moveFile(oldFile, newFile);
log.info("重命名成功,原名: [" + oldFileName + "],新名:["+ newFile.getName() + "]");
} catch (Exception e) {
log.info("操作失败---->>>>");
}
}
public static String printFileTimes(String filePath) throws IOException {
//System.out.println("\n***当前文件路径:" + filePath);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HHmmss"); // 指定日期格式
Path path = Paths.get(filePath);
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
FileTime lastModifiedTime = attrs.lastModifiedTime();
return sdf.format(new Date(lastModifiedTime.toMillis()));
}
/*
* 替换关键字
*/
public static String replaceKeyWord(String paramStr){
String [][] rePlaceStrArray = RepacleString.rePlaceStrArray;
for (String[] str: rePlaceStrArray){
String replaceStr = str[1];
if(paramStr.indexOf(replaceStr)!=-1){
return replaceStr.replaceAll(replaceStr,"");
};
}
return paramStr;
}
/*
* 是否是年份开头的文件名
* 2026-04-09 星期四 2202
*/
public static boolean isStartWithYear(String str){
String [] yearArray = {"2019","2020","2021","2022","2023","2024","2025","2026"};
for (String year:yearArray){
boolean bl = str.startsWith(year);
if(bl){
return bl;
}
}
return false;
}
public static void readFileCreateDateAndAddDate(String rootPath) throws IOException {
File folder = new File(rootPath);// 创建File对象
if(folder.isDirectory()){ // 使用isDirectory()方法检查是否为目录
log.info(rootPath + " 是一个文件夹。");
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
String fileName = file.getName();
if(isStartWithYear(fileName)){
log.info("文件名:" + fileName + ",是以指定年份开头的,不需要重新命名");
}else{
String filePath = rootPath + SystemInfoUtils.pathSeparator() + fileName;
log.info("文件名:" + fileName + ",路径:" + filePath);
String date = printFileTimes(filePath);
String filePathNew = rootPath + SystemInfoUtils.pathSeparator() + date + "_" + replaceKeyWord(fileName);
reNameFile(filePath,filePathNew);
}
}
}
}
}else{
log.info(rootPath + " 不是一个文件夹。");
}
}
/**
* 获取文件路径分隔符
* 2026-04-09 星期四 1843
* @return 文件路径分隔符
*/
public static String pathSeparator(){
String pathSeparator = System.getProperty("file.separator");
return pathSeparator;
}
public static void main(String[] args) throws IOException {
String rootPath = "H:\\Test_Test";
readFileCreateDateAndAddDate(rootPath);
}
}