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")) ; // 源编码
}
}
网友评论