因原项目是GBK编码的,现需要使用UTF-8编码。将项目导入UTF-8编码的编辑器后,出现中文乱码。
VsCode 可以转文件编码,但只能一个一个转,对于已经完成一起的项目,操作难免比较麻烦。
几经周转,特写一个程序,来完成文件编码问题
根据需求程序被设计为能对原项目完全拷贝并完成转码。
以下是将 GBK 编码的 originDir 项目 转化为 UTF-8编码的 destDir 项目的程序示例。
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
public class Main {
// 需要转码处理的文件后缀
public static String[] arr = {
"java","xml","js",
"project","MF","css",
"ftl","properties","ini",
"product"
};
// 原文件夹
public static String inputDirPath = "/tmp/originDir";
// 转码后存储的文件夹
public static String outputDirPath = "/tmp/destDir";
public static void main(String[] args) {
run(arr,inputDirPath,outputDirPath);
}
private static void run(String[] arr, String inputDirPath, String outputDirPath) {
File inputFile = new File(inputDirPath);
if(inputFile.isFile()){
// 文件处理
String destFilePath = outputDirPath.concat(File.separator).concat(inputFile.getName());
File destFile = new File(destFilePath);
fileHandle(inputFile,destFile);
return;
}
// 获取所有文件及文件夹
List<File> allFiles = FileUtil.getAllFiles(inputDirPath);
if(allFiles == null || allFiles.isEmpty()){
System.out.println("input dir is empty");
return;
}
// 判断是不是文件夹
for (File file: allFiles){
File destFile = buildDestFile(inputDirPath, outputDirPath, file);
if(file.isDirectory()){
// 文件夹处理
dirHandle(destFile);
}else{
// 文件处理
fileHandle(file, destFile);
}
}
}
private static boolean handleAble(File file, String[] arr) {
String fileName = file.getName();
int index = fileName.lastIndexOf(".");
if(index == -1){
System.out.println("文件:".concat(file.getAbsolutePath()).concat("不必处理"));
return false;
}
String extName = fileName.substring(index + 1);
for(String t: arr){
if(t.equals(extName)){
return true;
}
}
return false;
}
/**
* 数据处理
* @param file
* @param destFile
*/
private static void fileHandle(File file, File destFile) {
if(!file.isFile()){
return;
}
System.out.println("开始处理文件:" + file.getAbsolutePath());
System.out.println("目标文件路径为:" + destFile.getAbsolutePath());
System.out.println("");
boolean handleAble = handleAble(file,arr);
if(!handleAble){
moveFile(file,destFile);
}else{
convertFileEncoding(file, destFile);
}
}
/**
* move file
* @param file
* @param destFile
*/
private static void moveFile(File file, File destFile) {
try {
byte[] bytes = Files.readAllBytes(file.toPath());
Files.write(destFile.toPath(), bytes);
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("文件处理失败[move],待处理的文件:" + file.getAbsolutePath());
}
}
/**
* change file encoding and save in other place
* @param file
* @param destFile
*/
private static void convertFileEncoding(File file, File destFile) {
try {
// 读取文件
List<String> lines ;
try {
lines = Files.readAllLines(file.toPath(), Charset.forName("GBK"));
}catch (Exception e){
lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
}
// 转码
if(lines.isEmpty()){
return;
}
// 写到新的文件中
Files.write(destFile.toPath(),lines, StandardCharsets.UTF_8);
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("文件处理失败,待处理的文件:" + file.getAbsolutePath());
}
}
/**
* 文件夹处理
* @param destDir 目标文件夹
*/
private static void dirHandle(File destDir) {
if(destDir.exists()){
return;
}
boolean mkdirs = destDir.mkdirs();
if(!mkdirs){
throw new RuntimeException("file create failed!\r\n File Path : " + destDir.getPath());
}
}
/**
* 构建目标路径
* @param inputDirPath
* @param outputDirPath
* @param file
* @return
*/
private static File buildDestFile(String inputDirPath, String outputDirPath, File file) {
String filePath = file.getAbsolutePath();
String subFilepath = filePath.substring(inputDirPath.length());
String destFilePath = outputDirPath.concat(subFilepath);
return new File(destFilePath);
}
}
FileUtil
代码如下:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileUtil {
/**
* 获取指定文件夹下所有文件,含文件夹
* @param dirFilePath 文件夹路径
* @return
*/
public static List<File> getAllFiles(String dirFilePath){
if(dirFilePath == null || dirFilePath.isEmpty())
return null;
return getAllFiles(new File(dirFilePath));
}
/**
* 获取指定文件夹下所有文件,不含文件夹
* @param dirFile 文件夹
* @return
*/
public static List<File> getAllFiles(File dirFile){
// 如果文件夹不存在或着不是文件夹,则返回 null
if(dirFile == null || !dirFile.exists() || dirFile.isFile())
return null;
File[] childrenFiles = dirFile.listFiles();
if(childrenFiles == null|| childrenFiles.length == 0)
return null;
List<File> files = new ArrayList<>();
for(File childFile : childrenFiles) {
// 如果时文件,直接添加到结果集合
if(childFile.isFile()) {
files.add(childFile);
}else {
// 如果是文件夹。则先将其添加到结果集合,再将其内部文件添加进结果集合。
files.add(childFile);
List<File> cFiles = getAllFiles(childFile);
if(cFiles == null || cFiles.isEmpty()) continue;
files.addAll(cFiles);
}
}
return files;
}
}
该程序解决了编码转换的需求,经过整理,它有如下优点:
运行环境: JDK 1.8 +