所用腾讯微盘同步助手即时同步文件,图片文件也是设置默认保存在笔记目录下。Markdown 有一个问题就是文档中图片链接删除,源文件仍会存在于图片文件夹,下列这个程序可以对比并删除冗余的图片或资源文件(假删除,冗余文件将会移动到笔记文件夹中到 回收站 文件夹中,确定要删除时可以将整个文件夹手动删除)。

public class Main { static ArrayList<String> list= new ArrayList<>();
static String text;
public static void main(String[] args) { File file = new File("D:\\ 微云同步助手 \\QQ\\ 笔记 "); // 获取其 file 对象
// 获取其 file 对象
func(file);
for (String s : list) { String fileName = s.substring(s.lastIndexOf("\\") + 1, s.length());// 获取文件名
if (!text.contains(fileName)){ // 如果图片等资源在 md 内容中不存在即删除
System.out.println(fileName+" 删除成功 ");
String hs=file+"\\ 回收站 \\";
if (!new File(hs).exists())
new File(hs).mkdir();
new File(s).renameTo(new File(hs+fileName));
}
}
}
/**
* 遍历目录
* @param file
*/
private static void func(File file) { File[] fs = file.listFiles();
for (File f : fs) { if (f.isDirectory() && !f.toString().contains(" 回收站 ")) // 排除回收站目录
func(f);
if (f.isFile()) { // 若是文件,直接打印详细路径
String s = f.toString();
if (s.endsWith(".md")) {// 获取 md 文件内容
text += readToString(s);
} else { list.add(s);
}
}
}
}
/**
* 获取文本
* @param fileName
* @return
*/
public static String readToString(String fileName) {
String encoding = "UTF-8";
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try { FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
} catch (FileNotFoundException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace();
}
try { return new String(filecontent, encoding);
} catch (UnsupportedEncodingException e) { System.err.println("The OS does not support " + encoding);
e.printStackTrace();
return null;
}
}
}当然也可以用 BufferedReader
public class Main { static ArrayList<String> list= new ArrayList<>();
static StringBuilder text=new StringBuilder();
/**
* 暴力比较
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException { long start = System.currentTimeMillis();
File file = new File("D:\\ 坚果云 \\CodeNote"); // 获取其 file 对象
System.out.println(" 正在处理中……");
func(file);
for (String s : list) { String fileName = s.substring(s.lastIndexOf("\\") + 1, s.length());// 获取文件名
if (!text.toString().contains(fileName)){ // 如果图片等资源在 md 内容中不存在即删除
System.out.println(fileName+" 删除成功 ");
String hs=file+"\\ 回收站 \\";
if (!new File(hs).exists())
new File(hs).mkdir();
new File(s).renameTo(new File(hs+fileName));
}
}
long end=System.currentTimeMillis();
long time=end-start;
System.out.println(" 已完成,耗时 "+time+" ms, 请按任意键退出 ");
System.in.read();
}
/**
* 遍历目录
* @param file
*/
private static void func(File file) throws IOException { File[] fs = file.listFiles();
for (File f:fs) { if (f.isDirectory() && !f.toString().contains(" 回收站 ")) // 排除回收站目录
func(f);
if (f.isFile()) { // 若是文件,直接打印详细路径
String s = f.toString();
if (s.endsWith(".md")) {// 获取 md 文件内容
text.append(readToString(s));
System.out.println(" 读取 "+text.length()/1000+"K 个字符 ");
} else { list.add(s);
}
}
}
}
/**
* 获取文本
* @param fileName
* @return
*/
public static String readToString(String fileName) throws IOException { BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
StringBuilder txt = new StringBuilder();
while ((line = br.readLine()) != null) { txt.append(line);
}
br.close();
return txt.toString();
}
}再改进下吧,用正则,精确点匹配(也不是很精确,因为不同文件夹可能有同名文件,不过能保证一个文件夹有文件 a.png 跟 aaa.png 不至于都匹配上)
package com.company;
import java.io.*;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main { static ArrayList<String> list= new ArrayList<>();
static StringBuilder text=new StringBuilder();
public static void main(String[] args) throws IOException { ArrayList<String> picList = new ArrayList<>();
long start = System.currentTimeMillis();
File file = new File("D:\\ 坚果云 \\CodeNotes"); // 获取其 file 对象
System.out.println(" 正在处理中……");
func(file);
int i=0;
int delCount=0;
String ContentArea = text.toString();
String regex = "\\(assets/.*?\\.\\w+\\)";
Pattern pt=Pattern.compile(regex);
Matcher mt=pt.matcher(ContentArea);
while(mt.find()) { String replace = mt.group().replace("(assets/", "").replace(")", "");
picList.add(replace);
i++;
}
System.out.println(" 原文包含 "+i+" 张图片 ");
for (String s : list) { String fileName = s.substring(s.lastIndexOf("\\") + 1, s.length());// 获取文件名
int count=0;
for (String pic : picList) { if (pic.equals(fileName)){
count++;
}
}
if (count<=0){
delCount++;
// System.out.println(fileName+" 删除成功 ");
String hs=file+"\\ 回收站 \\";
if (!new File(hs).exists())
new File(hs).mkdir();
if (!new File(s).renameTo(new File(hs + fileName))){ new File(hs + fileName).delete();
new File(s).renameTo(new File(hs + fileName));
}
}
}
long end=System.currentTimeMillis();
long time=end-start;
System.out.println(" 已清理 "+delCount+" 张图片或文件,耗时 "+time+" ms, 请按任意键退出 ");
System.in.read();
}
private static void func(File file) throws IOException { File[] fs = file.listFiles();
for (File f:fs) { if (f.isDirectory() && !f.toString().contains(" 回收站 ")) // 排除回收站目录
func(f);
if (f.isFile()) { // 若是文件,直接打印详细路径
String s = f.toString();
if (s.endsWith(".md")) {// 获取 md 文件内容
text.append(readToString(s));
} else { list.add(s);
}
}
}
}
public static String readToString(String fileName) throws IOException { BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
StringBuilder txt = new StringBuilder();
while ((line = br.readLine()) != null) { txt.append(line);
}
br.close();
return txt.toString();
}
}