最近终于把接手的工作梳理完毕, 虽然积重难返, 但是很多地方还是我重新做了规矩, 比较方便.
- 处理cue文件
- 递归一次性干完
lambda表达式
前两天给女儿听歌的时候, 找了王菲的无损专辑, 顺便还把老婆的最爱 - 孙燕姿的无损专辑找了下来.
听无损当然首选还是foobar了, 到foobar官网发现这个软件还在更新, 这都20多年了, 确实还是有人维护.
下了最新版之后, 把cue文件导入, 发现一个问题就是乱码, 而且只有中文乱码, 打开cue文件发现cue文件都是UTF-8格式的, 那么可能foobar显示的时候是用windows默认的GBK来解析, 所以就出现问题.
然后就尝试了一下, 将UTF-8文件通过notepad++打开, 强制转换成GB2312, 结果发现乱码显示的部分和foobar果然是一致的.
那么要解决的问题就很清楚了, 就是把一个UTF-8编码的文件读入之后, 再以GBK的格式写入一个新文件就可以了, foobar就可以正常读取了. 这里正好再回头练一下Java的老IO库.
实际写出的代码如下:
import java.io.*;
public class ProcessCueFile {
//处理方法
public void process(String path, boolean override) throws IOException {
File file = new File(path);
//获取文件名
String fileName = file.getName();
//InputStream, 用于从其中读取全部的字节数组
FileInputStream inputStream = new FileInputStream(path);
byte[] result = inputStream.readAllBytes();
//用UTF-8格式解析字符串, 在内部, Java会用UTF-8解析读入的字符数组, 然后又会将其转换成Java的内部编码UTF-16字符的字符串
String changedString = new String(result, StandardCharsets.UTF_8);
//将Java内部编码的字符串按照GB2312编码成字节数组
byte[] toWrite = changedString.getBytes(""GB2312"");
//根据是否覆盖来生成新的文件名
String newFileName;
//如果不覆盖, 生成new开头的新文件名
if (!override) {
newFileName = file.getParent() + ""\\new"" + fileName;
//如果覆盖, 就是原来文件名
} else {
newFileName = path;
}
FileOutputStream fileOutputStream = new FileOutputStream(newFileName);
//将GBK编码的字节数组写入到文件中
fileOutputStream.write(toWrite);
fileOutputStream.close();
System.out.println(""已经将文件写入至: "" + newFileName);
}
public static void main(String[] args) throws IOException {
String path = ""D:\\downloads\\music\\王菲\\1997《王菲 同名专辑》97内地引进版\\王菲 - 同名专辑.cue"";
ProcessCueFile processor = new ProcessCueFile();
processor.process(path);
}
}
如果到网上去搜, 这个解决办法就太费劲了, 需要将cue文件改名成txt, 复制到浏览器里, 转换编码, 会得到乱码, 再把乱码复制到txt里, 手工把中文字乱码改掉......
上边这段程序运行后, 就会在源cue文件的相同位置生成一个GB2312编码的cue文件, 其实也完全可以替换原来文件直接写入, 不过还是保险一点. 这可比手工更改需要替换乱码要高效的多了.
递归一次性干完
处理这种玩意, 当然是要一次性搞完才行, 所以就继续编写遍历目录的函数, 找到其中所有的cue文件进行处理:
private void recursionProcessFiles(String path, boolean override) throws IOException {
File currentPath = new File(path);
//是文件就判断cue文件然后处理, 默认是覆盖
if (currentPath.isFile()) {
if (currentPath.getName().endsWith("".cue"")) {
System.out.println(""当前处理的是: "" + currentPath);
//调用处理路径的方法
process(currentPath.getAbsolutePath(), override);
}
//不是文件就递归处理, 将其中所有路径遍历然后继续处理
} else {
File[] fileList = currentPath.listFiles();
if (fileList == null) {
return;
}
for (File f : fileList) {
recursionProcessFiles(f.getAbsolutePath(), override);
}
}
}
这递归函数和我录制过的视频中的遍历所有xlsx文件如出一辙, 都是一样的套路, 就不再多说了.
然后拖了几张王菲的专辑进来, 将foobar的媒体库设置成存放目录, 一开始都乱码, 使用覆盖执行了一次, 瞬间全部搞定, 妥妥的.
每天能解决一些小问题的感觉确实很好.