简书的文章需要搬运到hexo上,手动太麻烦。于是用Java写了一个自动转换的工具。文章不在简书上也可以,转换规则为 总目录(root)->子目录(分类名)->文章(文件名就是标题)
效果可以看我的博客
- 环境
jdk1.8
- 简书设置里的打包下载全部文章,解压。解压后目录就是源文件目录root
- 根据文集自动标记
hexo
的分类 - 增加字数统计,推荐阅读时间功能。(英文单词和中文的个数)
- 我自己是写java的,文件名出现
@
字符,统一替换成了注解
。(文件名即标题)
如果不需要可以删除.replaceAll("@","注解")
- 使用字节流,没有用字符流。懒得换了,不影响使用。
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author colin.cheng
* @version V1.0
* @date Created In 17:54 2019/6/26
*/
public class test1 {
//文章计数器
public static int count = 0;
//字数计数器
public static int charCount=0;
public static Pattern p = Pattern.compile("[\u4e00-\u9fa5]|[a-zA-Z]+|[1-9]|[,.,。??]", Pattern.CASE_INSENSITIVE);
public static void main(String[] args)throws Exception {
//源文件根目录root
final String rootPath = "G:\\chromedownload\\user-xxx\\mynote";
//转换后文章存放目录
final String toPathAdd = "F:\\hexoBlog\\greatcolin\\source\\_posts";
Path root = Paths.get(rootPath);
Path target = Paths.get(toPathAdd);
//存放目录则不存在新建
if(!Files.exists(target)){
Files.createDirectories(target);
}
Files.walkFileTree(root,new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
int oneNoteCount = 0;
String fileName = file.getFileName().toString().replaceAll("@","注解");
//创建转换后的文件
Path toPath = Paths.get(toPathAdd+"\\"+fileName);
if(!Files.exists(toPath)){
toPath = Files.createFile(toPath);
System.out.println("create"+toPath);
}
FileOutputStream fop;
if(Files.exists(toPath)){
fop = new FileOutputStream(toPath.toFile());
}else {
System.err.println("不存在"+toPath);
return null;
}
FileInputStream fip = new FileInputStream(file.toFile());
//头
String noteClass = file.getParent().toString();
String[] className = noteClass.split("\\\\");
//根据文件夹名称获取分类名
noteClass = className[className.length-1];
//创建头部,写入
byte[] headBuf = createHead(fileName,noteClass);
fop.write(headBuf);
//读取文件,写入
int read = 0;
byte[] buf = new byte[1024];
while((read=fip.read(buf))>=0){
String a = new String(buf).replaceAll("[^0-9a-zA-Z\u4e00-\u9fa5]+","");
int count = countNote(a);
charCount += count;
oneNoteCount += count;
}
int time = Math.ceil(oneNoteCount/250)>=1?(int)Math.ceil(oneNoteCount/250):1;
fop.write(new String("文章字数:"+oneNoteCount+",阅读全文大约需要"+time+"分钟\r\n").getBytes());
fip.close();
fip = new FileInputStream(file.toFile());
while((read=fip.read(buf))>=0){
fop.write(buf,0,read);
}
fip.close();
fop.close();
System.out.println(fileName+" 转换成功");
count++;
return FileVisitResult.CONTINUE;
}
});
System.out.println("执行完成,总共转换"+count+"篇文章。中英文总字/词数达到"+charCount);
}
/**
* 生成文章头部信息
* @param title 标题
* @param noteClass 分类
* @return
*/
public static byte[] createHead(String title,String noteClass){
StringBuilder headStr = new StringBuilder("---\r\n");
title = title.replaceAll(".md","");
headStr.append("title: "+title+"\r\n");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
headStr.append("date: "+sdf.format(new Date())+"\r\n");
headStr.append("categories: "+noteClass+"\r\n");
headStr.append("tags: \r\n");
headStr.append("---\r\n");
return headStr.toString().getBytes();
}
/**
* 计算字数
* @param note
* @return
*/
public static int countNote(String note){
Matcher m = p.matcher(note);
int count = 0;
while (m.find()) {
count++;
}
return count;
}
}
此文中的文件创建时间是固定的,我另写了一个工具可以获取文章的发布日期。简书文章获取时间