【文件编码转换】将GBK编码项目转为UTF-8编码项目

需求

因原项目是GBK编码的,现需要使用UTF-8编码。将项目导入UTF-8编码的编辑器后,出现中文乱码。

调研

VsCode 可以转文件编码,但只能一个一个转,对于已经完成一起的项目,操作难免比较麻烦。

几经周转,特写一个程序,来完成文件编码问题

能力设计

根据需求程序被设计为能对原项目完全拷贝并完成转码。

  • 能对输入文件、文件夹。若输入文件,则对该文件进行转码;如输入文件夹,则对文件夹中所有的文件进行编码。
  • 能根据文件类型进行过滤处理
  • 能对输入文件夹进行目录结构完全copy。

以下是将 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 {
    /**
     *  <h1>获取指定文件夹下所有文件,含文件夹</h1>
     * @param dirFilePath 文件夹路径
     * @return
     */
    public static List<File> getAllFiles(String dirFilePath){
        if(dirFilePath == null || dirFilePath.isEmpty())
            return null;
        return getAllFiles(new File(dirFilePath));
    }

    /**
     *  <h1>获取指定文件夹下所有文件,不含文件夹</h1>
     * @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;
    }
}

总结

该程序解决了编码转换的需求,经过整理,它有如下优点:

  • 可以自由配置输入文件夹输出文件夹。如果输入文件是一个文件,则对该文件进行编码,并存储到输出文件夹中
  • 可以修改编码满足其他编码方式的转变,如将 UTF-8 转为 GBK
  • 可以配置需要转换的文件路径,细致化控制

运行环境: JDK 1.8 +

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值