视频讲解
效果
实现将某个文件中所有的本地图片移动到指定目录,并替换md文件中所有的图片的路径到对应目录
- 已适配同行多图的情况
如下图所示,改文件里的图片分布在多个本地目录中
日志显示图片移动情况
实现代码
注释很详细了,直接看注释就好了,不太理解的话可以看我b站的视频解析
package online.longzipeng.mywebdemo.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @author lzp
* @Date:2023/3/8
* @description: markdown 文件的一些处理
*/
@Slf4j
public class MarkdownFileUtils {
/**
* 匹配markdown文件中图片的正则表达式 ,元组1中为图片描述,元组2中为图片地址 ![描述信息](图片的真实地址)
*/
private static final String regexImg = "!\\[(.*?)\\]\\((.*?)\\)";
/**
* 移动本地markdown文件中的图片到指定目录
* 注意: 重名图片会直接覆盖!!
*
* @param mdPath markdown 文件的路径
* @param targetImgDir 图片移动的目标文件夹
* @param onlyCopy 是否只是复制图片
*/
public static void moveImage(String mdPath, String targetImgDir, boolean onlyCopy) {
/// 先全部路径替换为 /分割 保证路径统一
String filePath = formatPath(mdPath);
targetImgDir = formatPath(targetImgDir);
// 通过设置的md文件路径取到相对路径 ,主要用于组装相对路径的图片真实路径
/// 切割出相对路径
String relativePath = filePath.substring(0, filePath.lastIndexOf("/") + 1);
FileReader fileReader = new FileReader(filePath);
// 从文件中读取内容为字符串
String readString = fileReader.readString();
// 最后覆盖输出的调整好的文件内容
// 编译正则表达式
Pattern patten = Pattern.compile(regexImg);
// 指定要匹配的字符串
Matcher matcher = patten.matcher(readString);
List<String> matchImagePaths = new ArrayList<>();
// 将匹配到的完整图片信息装入集合中, 此处find()每次被调用后,会偏移到下一个匹配
while (matcher.find()) {
matchImagePaths.add(matcher.group());
}
// 获取当前目录下的所有md文件中的所有图片链接, 这里$2取的时正则中第二个元组内包含的数据
Set<String> imagePaths = matchImagePaths.stream().map(v -> v.replaceAll(regexImg, "$2")).collect(Collectors.toSet());
log.info("已提取出{}张图片,开始迁移图片", imagePaths.size());
int moveCount = 0;
for (String imgPath : imagePaths) {
// 这里用一个新的变量来存真正的img地址,imgPath保留原值,用于后续替换地址
String realImagePath = formatPath(imgPath);
// 分别通过绝对路径和相对路径创建图片
if (!FileUtil.exist(realImagePath)) {
// 走绝对路径不存在,说明是相对路径,此时用文件的路径进行拼接
realImagePath = relativePath + realImagePath;
}
if (FileUtil.exist(realImagePath)) {
// 将图片复制到对应地址
String targetImgPath = targetImgDir + realImagePath.substring(realImagePath.lastIndexOf("/"));
log.info("原图片:{} 即将迁移到:{}", realImagePath, targetImgPath);
// 待处理图片路径与原路径不一样时才处理
if (!StrUtil.equals(imgPath, targetImgPath)) {
// 复制或者移动图片
if (onlyCopy) {
FileUtil.copy(new File(realImagePath), new File(targetImgPath), true);
} else {
FileUtil.move(new File(realImagePath), new File(targetImgPath), true);
}
// 原文件中所有该 原路径图片地址,替换为目标图片路径
readString = readString.replace(imgPath, targetImgPath);
moveCount++;
}
}
}
// 文件写入
FileWriter fileWriter = new FileWriter(filePath);
fileWriter.write(readString);
log.info("===========================");
log.info("文件写入完毕!!");
log.info("成功移动{}张图片", moveCount);
}
/**
* 格式化路径 ,将 \ 【反斜杠】 全部替换为 / 【正斜杠】
*/
public static String formatPath(String path) {
return path.replaceAll("\\\\", "/");
}
public static void main(String[] args) {
// 需要调整图片位置的md文件
String filePath = "E:\\我的坚果云\\笔记\\java\\xxx.md";
// 移动图片到目标目录
String targetImgDir = "E:\\我的坚果云\\笔记\\java\\xxx\\imgs";
moveImage(filePath, targetImgDir, true);
}
}
~~