GBK(GB2312)与UTF-8文件转码

最近使用的Intelij IDEA开发工具,转码有点小问题。百度了一下,Eclipse可以自动转码,而IDEA却不可以。总是需要手动去转若要把源文件由GBK转成UTF-8的,得靠其他方式了。网上搜罗了一下方法,然后自己整理了一下。现把代码贴出来,测试OK、可以直接使用!

需要的四个jar包,分别是:“antlr-2.7.6.jar”、“commons-io-2.4.jar”、“cpdetector_1.0.5 .jar”、“jchardet-1.0.jar”    网上可以直接下载,根据下面的方法。可以把任意的编码换成你想要的。转成新编码以后的文件把源文件覆盖掉就可以了

 

package com.company;

import cpdetector.io.ASCIIDetector;
import cpdetector.io.CodepageDetectorProxy;
import cpdetector.io.JChardetFacade;
import cpdetector.io.UnicodeDetector;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;

public class Main {
    privatestatic int fileCount = 0;
    privatestatic int convertedCount = 0;

    publicstatic void main(String[] args) {
        //源路径
       
String primaryPath = "E:\\ WorkSpace\\Test\\src\\com";
        //目标路径
       
String targetPath = "E:/src";
        //获取所有java文件
        utf8AndGbkConvert
(primaryPath,targetPath, false);

    }

    /**
     * UTF8
和GBK(GB2312)互相转换
     *
     * @param
primaryPath 源文件路径
     * @param
targetPath  目标文件路径
     * @param
isUtf8ToGbk 是否是UTF-9转成GBK  true表示UTF-8转成GBK(GB2312) false表示GBK(GB2312)转成UTF-8
     */
   
public static void utf8AndGbkConvert(StringprimaryPath, String targetPath, boolean isUtf8ToGbk) {
        Collection<File> javaPrimaryFiles = FileUtils.listFiles(new File(primaryPath), new String[]{"java"}, true);
        fileCount= javaPrimaryFiles.size();
        for (File javaPrimaryFile :javaPrimaryFiles) {
            try {
                String chatsetName = judgeChatsetByFile(javaPrimaryFile);
                String newFilePath =targetPath + javaPrimaryFile.getAbsolutePath().substring(primaryPath.length());
                newFilePath =newFilePath.replaceAll("\\\\", "/");

                if (isUtf8ToGbk) {
                    if (chatsetName.equalsIgnoreCase("UTF-8")) {
                        //如果是源文件为UTF-8则转换成GBK,
                       
FileUtils.writeLines(new File(newFilePath), "GBK", FileUtils.readLines(javaPrimaryFile,"UTF-8"));
                    } else {
                        //不是则直接复制
                       
File f = new File(newFilePath.substring(0, newFilePath.lastIndexOf("/")));
                        if (!f.exists()) f.mkdirs();
                        File newFile = new File(newFilePath);
                        if (!newFile.exists())newFile.createNewFile();
                        FileUtils.copyFile(javaPrimaryFile,newFile);
                    }
                } else {
                    if (chatsetName.equalsIgnoreCase("GBK") || chatsetName.equalsIgnoreCase("GB2312")) {
                        //如果是源文件为GBK或者GB2312则转换成UTF-8,

                       
FileUtils.writeLines(new File(newFilePath), "UTF-8", FileUtils.readLines(javaPrimaryFile,chatsetName));
                    } else {
                        File f = new File(newFilePath.substring(0, newFilePath.lastIndexOf("/")));
                        if (!f.exists()) f.mkdirs();
                        File newFile = new File(newFilePath);
                        if (!newFile.exists())newFile.createNewFile();
                        FileUtils.copyFile(javaPrimaryFile,newFile);
                    }
                }

            } catch(IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("fileCount:" + fileCount);
        System.out.println("convertedCount:" + convertedCount);

    }

    publicstatic String judgeChatsetByFile(File f) {

        CodepageDetectorProxy detector =CodepageDetectorProxy.getInstance();


        //detector.add(new ParsingDetector(false)); //如果不希望判断xml的encoding,而是要判断该xml文件的编码,则可以注释掉

       
detector.add(JChardetFacade.getInstance());

        //ASCIIDetector用于ASCII编码测定

       
detector.add(ASCIIDetector.getInstance());

        //UnicodeDetector用于Unicode家族编码的测定

       
detector.add(UnicodeDetector.getInstance());

        Charset charset = null;
        try {
            charset =detector.detectCodepage(f.toURL());
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        String codeName = "";
        if (charset != null) {
            System.out.println(f.getName() + "编码是:" + charset.name());
            convertedCount++;
            codeName = charset.name();
        } else {
            System.out.println(f.getName() + "未知");
            codeName = "UNKOWN";
        }
        returncodeName;
    }
}

 

当出现"'utf-8' codec can't decode byte 0xba in position 2: invalid start byte"错误时,通常是因为编码问题导致的。根据引用和引用的内容,我可以给出一些解决方法。 首先,确认文件是否是utf-8格式,可以使用文本编辑器(比如sublime)打开文件查看,如果乱码,则文件很可能不是utf-8编码。如果是在Windows上,还需确认文件是否开头含有BOM格式,如果有,需要去掉BOM头尝试。另外,也有可能文件是二进制文件,可以使用"rb"模式打开进行测试。可以使用chardet模块的`chardet.detect(bytes_content)`方法测试当前编码,然后根据需要进行decode等转码操作。 一个示例解决方法是,将打开文件的代码中的打开模式改为"rb",即使用`f = open(file,'rb')`。这样,文件将以二进制模式打开,可以避免编码问题。 另一个示例解决方法是,尝试将'utf-8'改为其他编码,比如GB2312gbk、ISO-8859-1。可以在打开文件时指定`encoding='utf-8'`,例如`f = open('txt01.txt',encoding='utf-8')`,将'utf-8'替换为其他编码名称。 通过以上方法,您可以解决"'utf-8' codec can't decode byte 0xba in position 2: invalid start byte"错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [错误:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbc in position 2: invalid start byte的...](https://blog.csdn.net/Rose_IT/article/details/98875355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [python打开文件报:'utf-8' codec can't decode错误](https://blog.csdn.net/u011550708/article/details/79655623)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值