大数据平台技术笔记

批量修改文件编码

2022-06-07  本文已影响0人  OkGogogooo

1. 功能

批量将某几种编码的文件转变成另一种编码的文件。例如将GBK编码的文件转成UTF-8编码的文件

2. 代码

public class StreamAssist
{
    /**
     * 修改下面文件的编码
     */
    public static void changeEncode(File aDir , FileFilter aFilter , Charset aTargetCharset , Charset... aPossibles)
    {
        File[] files = aDir.listFiles(aFilter) ;
        if(files != null && files.length>0)
        {
            List<File> dirs = new ArrayList<>() ;
            for(File file : files)
            {
                if(file.isDirectory())
                    dirs.add(file) ;
                else
                {
                    byte[] data = toBytes(file) ;
                    ByteBuffer buf = ByteBuffer.wrap(data) ;
                    if(!isCompatible(aTargetCharset, buf))
                    {
                        for(Charset charset : aPossibles)
                        {
                            // 检测一下编码,避免搞错了
                            if(XString.isCompatible(charset, buf))
                            {
                                try(Writer writer = new OutputStreamWriter(new FileOutputStream(file) , aTargetCharset)
                                        ; InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(data), charset))
                                {
                                    int ch ;
                                    while((ch=reader.read()) != -1)
                                        writer.write(ch) ;
                                    break ;
                                }
                                catch(Exception e)
                                {
                                    Log.warn("编码转换({} --> {})失败!文件:{}" , charset.name() , aTargetCharset.name() 
                                            , file.getAbsolutePath()) ;
                                }
                            }
                        }
                    }
                }
            }
            if(dirs.size()>0)
            {
                for(File dir : dirs)
                    changeEncode(dir, aFilter, aTargetCharset, aPossibles);
            }
        }
    }
    /**
    * 将文件加载成byte[]。文件的大小不应该过大
    **/
    public static byte[] toBytes(File aFile)
    {
        ByteArrayOutputStream outs = new ByteArrayOutputStream() ;
        try(FileInputStream ins = new FileInputStream(aFile))
        {
            byte[] bs = new byte[1024] ;
            int len = 0 ;
            while((len=ins.read(bs))>0)
            {
                outs.write(bs, 0, len) ;
            }
            outs.flush() ;
            return outs.toByteArray() ;
        }
        catch (FileNotFoundException e)
        {
            return null ;
        }
        catch (IOException e)
        {
            WrapException.wrapThrow(e) ;
            return null ;       // dead code
        }
    }
    /**
    * 检查字节数组和指定的编码是否相配
    **/
    public static boolean isCompatible(Charset aCharset , ByteBuffer aBytes)
    {
        try
        {
            aBytes.rewind() ;
            aCharset.newDecoder().onUnmappableCharacter(CodingErrorAction.REPORT).decode(aBytes) ;
            return true ;
        }
        catch (CharacterCodingException e)
        {
            return false ;
        }
    }
}

3.调用测试

public class Test
{

    public static void main(String[] args)
    {
        String dirPath = "/xxx/src/main/java" ;
        StreamAssist.changeEncode(new File(dirPath) 
                , (f)->f.isDirectory() || f.getName().endsWith(".java")
                , AppContext.sUTF8               //目标编码
                , Charset.forName("GBK")) ;      // 源编码
    }

}
上一篇下一篇

猜你喜欢

热点阅读