`
xxjkcyt
  • 浏览: 5544 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java文件编码转换工具

 
阅读更多

                                                           Java文件编码转换工具   

        由于每个人的项目源码的编码设置不同,造成版本库上的代码下载下来之后中文出现乱码,可以单独在Eclipse里面对每个文件更改编码方式,然后拷贝出内容,在恢复成原来的编码,然后再粘贴内容,就可以去除乱码,但是这样做很麻烦。空闲之余,本人写了个批量转码的工具。

        转码实现主要用到 jdk 中的 CharsetEncoder 和 CharsetDecoder.下面贴上代码:

 

/**

 * 实施转码操作

 * @author 储玉庭

 */

public class ChannelIO {

private ReadableByteChannel channelIn;

private WritableByteChannel channelOut;

private CharsetEncoder encoder;

private CharsetDecoder decoder;

private ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

private Stack<Byte> reservedBytes = new Stack<Byte>();

private ByteBuffer swapSpace;

private boolean eof;

 

public ChannelIO(ReadableByteChannel in, WritableByteChannel out,

CharsetEncoder encoder, CharsetDecoder decoder) {

this.channelIn = in;

this.channelOut = out;

this.encoder = encoder;

this.decoder = decoder;

}

 

public void reset(ReadableByteChannel in, WritableByteChannel out,

CharsetEncoder encoder, CharsetDecoder decoder) {

this.channelIn = in;

this.channelOut = out;

this.encoder = encoder;

this.decoder = decoder;

}

 

public void reset() {

eof = false;

this.channelIn = null;

this.channelOut = null;

this.encoder = null;

this.decoder = null;

reservedBytes.clear();

buffer.clear();

if (null != swapSpace)

{

swapSpace.clear();

}

}

 

public void transfer() throws IOException {

long bytesRead = 0;

long tmpBytesRead = 0;

buffer.clear();

while ((tmpBytesRead = fillInBuffer(buffer)) != -1) {

buffer.flip();

byte[] data = encodeLoop(buffer);

channelOut.write(ByteBuffer.wrap(data));

bytesRead += data.length;

buffer.clear();

}

}

 

private int fillInBuffer(ByteBuffer buffer) throws IOException {

int totalBytesRead = 0;

while (!reservedBytes.isEmpty()) {

buffer.put(reservedBytes.pop());

totalBytesRead++;

}

 

int bytesRead = channelIn.read(buffer);

if (-1 != bytesRead) {

totalBytesRead += bytesRead;

} else {

eof = true;

}

 

if (totalBytesRead == 0)

totalBytesRead = -1; // indicates end of file

return totalBytesRead;

}

 

private byte[] encodeLoop(ByteBuffer bufferData)

throws CharacterCodingException {

CoderResult result = null;

ByteBuffer tmpBuffer = null;

int dataLimit = bufferData.limit();

int preferedSize = dataLimit;

boolean exceptionOccurrerd;

do {

try {

exceptionOccurrerd = false;

CharBuffer cBuffer = decoder.decode(bufferData);

bufferData.flip();

tmpBuffer = allocateBuffer(cBuffer, preferedSize);

result = encoder.encode(cBuffer, tmpBuffer, eof);

tmpBuffer.flip();

preferedSize = preferedSize * 3 / 2;

} catch (Exception e) {

reservedBytes.push(bufferData.get(dataLimit - 1));

bufferData.position(dataLimit - 1);

bufferData.flip();

decoder.reset();

dataLimit = dataLimit - 1;

exceptionOccurrerd = true;

}

} while (null != result && result.isOverflow() || exceptionOccurrerd);

 

byte[] data = new byte[tmpBuffer.limit()];

tmpBuffer.get(data);

return data;

}

 

private ByteBuffer allocateBuffer(CharBuffer cBuffer, int preferedSize) {

int totalChars = cBuffer.limit();

int requiredSize = Math.max(

(int) (totalChars * encoder.averageBytesPerChar()),

preferedSize);

if (null == swapSpace || swapSpace.capacity() < requiredSize) {

swapSpace = ByteBuffer.allocate(requiredSize);

}

swapSpace.clear();

return swapSpace;

}

}

 

/**

 * 扫描目录下的所有源码,并调用ChannelIO实施转码

 * @author 储玉庭

 */

public class Convertor {

private static ChannelIO transfer = new ChannelIO(null, null, null, null);

private File rootDir;

private String srcEncoding;

private String destEncoding;

 

public Convertor(File srcDir, String sourceEncoding, String destEncoding)

throws IOException {

if (null == srcDir || !srcDir.exists() || !srcDir.isDirectory()) {

throw new IOException(

"Please specify an existing source file directory!");

}

this.rootDir = srcDir;

this.srcEncoding = sourceEncoding;

this.destEncoding = destEncoding;

}

 

public final void convert(File[] files) throws IOException {

 

for (File srcFile : files) {

try {

convert(srcFile);

} catch (IOException e) {

               System.err.println("Error occurred while convering file: [" + srcFile + "]");

}

}

}

 

public final void convert(File file) throws IOException {

if (null == file || !file.exists()) {

throw new IOException("File [" + file.getCanonicalPath()

+ "] does not exist");

}

 

if (file.isDirectory()) {

convert(file.listFiles());

}

 

if (!file.getName().endsWith(".java")) {

return;

}

 

File tmpFile = new File(file.getCanonicalPath() + ".tmp");

 

ReadableByteChannel channelIn = null;

WritableByteChannel channelOut = null;

boolean succ = false;

try {

channelIn = getChannelForRead(file);

channelOut = getChannelForWrite(tmpFile);

transfer.reset(channelIn, channelOut,

EncodingUtil.getEncoder(destEncoding),

EncodingUtil.getDecoder(srcEncoding));

transfer.transfer();

succ = true;

} finally {

closeChannel(channelIn);

closeChannel(channelOut);

transfer.reset();

if (succ) {

file.delete();

tmpFile.renameTo(file);

}

}

}

 

private static final void closeChannel(Channel channel) {

if (null != channel) {

try {

channel.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

private static final ReadableByteChannel getChannelForRead(File file)

throws FileNotFoundException {

return new FileInputStream(file).getChannel();

}

 

private static final WritableByteChannel getChannelForWrite(File file)

throws FileNotFoundException {

return new FileOutputStream(file).getChannel();

}

 

public static void main(String[] args) throws IOException {

if (null == args || args.length < 3) {

System.err

.println("Usage: java Convertor <File Dir> <source encoding> <target encoding>");

System.exit(-1);

}

 

Convertor convertor = new Convertor(new File(args[0]), args[1], args[2]);

convertor.convert(convertor.rootDir.listFiles());

}

}

 

/**

 * 缓存 CharsetEncoder 和 CharsetDecoder

 * @author 储玉庭

 */

public class EncodingUtil {

 

private static final Map<String, CacheEntry<Charset>> charsetCache = new WeakHashMap<String, CacheEntry<Charset>>(

5);

 

public static CharsetEncoder getEncoder(String destEncoding) {

Charset cs = findFromCache(destEncoding);

return cs.newEncoder().onMalformedInput(CodingErrorAction.REPORT)

.onUnmappableCharacter(CodingErrorAction.REPORT);

}

 

public static CharsetDecoder getDecoder(String sourceEncoding) {

Charset cs = findFromCache(sourceEncoding);

return cs.newDecoder().onMalformedInput(CodingErrorAction.REPORT)

.onUnmappableCharacter(CodingErrorAction.REPORT);

}

 

private static Charset findFromCache(String encodingName) {

synchronized (charsetCache) {

CacheEntry<Charset> entry = charsetCache.get(encodingName);

if (null == entry) {

entry = new CacheEntry<Charset>();

entry.name = encodingName;

entry.value = Charset.forName(encodingName);

charsetCache.put(encodingName, entry);

}

return entry.value;

}

}

 

private static final class CacheEntry<V> {

private String name;

private V value;

 

public String name() {

return name;

}

 

public V value() {

return value;

}

}

}

分享到:
评论

相关推荐

    JAVA文件编码转换工具1.50base[jar文件]

    JAVA文件编码转换工具1.50base 默认gbk编码转utf8编码 需要java虚拟机支持 jar文件,linux下终端使用 java -jar 文件名运行 选择文件 重命名文件为原文件名+".bak" 执行编码转换,创建新文件为原文件名 选择文件夹...

    java文件编码转换工具v1.10base[JAR文件]

    JAVA文件编码转换工具1.10base[JAR文件] 默认gbk编码转utf8编码 选择文件 重命名文件为原文件名+".bak" 执行编码转换,创建新文件为原文件名 选择文件夹 文件过滤生效 附带GBK编码文件news.sql 有问题请邮件我:hj...

    文件编码转换工具java

    该小工具是用java开发的,只要装有java虚拟机就可以直接运行,另外,jar文件中有源码,可以扩展

    文件编码转换工具

    该工具用于更改项目文件编码 最近发现项目中有编码问题有些是gbk的有些是utf-8的,为了统一改为utf-8, 不得不一个个更改,项目小文件少没关系,如果很大就令人头疼啦。不过有了这个工具只要几秒钟就可以搞定啦! 不...

    文件编码批量转换工具(不用积分)

    2,文件编码自动识别,所以使用的时候不用提供原文件的编码;识别不了不会转换,保证项目文件的安全 3,支持utf-8-bom编码 4,兼容Linux & Windows & Mac系统 5,不用安装,只要机器有JDK就可以使用 需要源码的请...

    批量字符编码转换工具,批量转换文件编码 超级批量编码转换

    批量转换文件编码 超级批量编码转换 批量转换编码 编码批量转换工具 批量转换txt编码 linux 批量转换编码 编码格式批量转换 php 字符编码转换 字符编码转换 java 字符编码转换

    java项目编码转换工具类

    简单的编码环境转换工具类,适用于批量修改目录中纯文本代码文件和其他纯文本,例如utf-8转gbk,gbk转utf-8,如果有需要过滤其他文件可自行加入转换过滤规则,下载之后修改一下导包就可以运行成功了。

    swt文件编码转换工具

    swt文件编码转换工具;附件中包括源码和执行文件;双击FileCharSet_fat.jar即可执行(前提条件要有java环境)。

    自己一个java写的编码转换工具

    自己一个java写的编码转换工具 可批量转换文件 运行后编码自己指定

    文件编码转换工具(源码)

    可以将一个文件夹目录下的文件轻松转换成你想要的编码格式(可扩展).

    项目编码转换工具

    该工具使用java所写,所以运行需要有java环境。该工具可以指定项目目录转换该项目下的指定后缀名(如:.java .cs .as等等)的文件编码。该工具不修改原项目文件,会在原项目的同级目录下生成转换后的项目。

    堪称完美的文件编码转换工具(含源码)

    1.选择你要转换的文件或文件夹的原来的编码方式和目标编码方式。 2.选择需要转换编码方式的文件或文件夹。 3.单击转换按钮。 默认要转换的文件格式为: .txt .h .cpp .c .java .cs .asp .aspx .js .master .css .htm...

    java实现文件编码转换的方法

    主要为大家详细介绍了java实现文件编码转换的方法,分享一个文件编码转换的工具类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    批量转化文件编码工具(附Java源码)

    此工具为自己开发的有图形界面的 批量文件转码工具。 支持多种转码,如果gbk、gb2312、utf-8等的互转。

    java视频转换工具类(附带转换工具类)

    java视频转换工具类,可将视频任意转换为mp4、ogg、flv等多种格式

    xmljava系统源码-FilesCodingConvert:批量文件编码格式转换工具

    #批量文件编码格式转换工具 ##简介 最近开始学习使用Android Studio,因为它的方便易用,我打算以后就不在使用ADT的方式编写Android项目了。当从Eclipse项目向AS项目迁移时遇到了一个问题,就是文件编码格式的问题,...

    Java源码编码转换器 v2.0 GBK TO UTF8

    修正之前版本一些UTF-8转换后乱码的Bug 附上NChardet源码 可用于转换java文件为指定格式编码工具(内付源码),自动检测文件的编码类型

    使用 Java 对 Linux 下文件编码格式进行批量转换源代码

    测试使用说明: 1。将 字符集编码格式为 GB2312 的文件 test0.java,test...使用本工具可以对 Linux 下文件的字符集编码格式进行批量转换。只需适当配置一下,可以批量处理各种文件格式的文件,如 *.txt,*.java 等等。

    convert-编码转换工具

    我根据juniversalchardet(感觉准确率高一点)写了一个带图形界面的编码转换工具[ file-convert ]放在googlecode.附带源码,Util包具有较好重用性:基于包装器模式的文件过滤器链 基于java的native2ascii实现(借用自...

    eclipse文件编码设置、转换原理与实用工具

    批量转换文件的二进制编码(用新的文件编码重写文件),如从gbk到utf-8,免除逐个文件全选、复制、右键、属性、改文本文件编码、粘贴、保存之苦(该转换是根据编码设置文件进行转换的,因此更加安全); c.结合上述...

Global site tag (gtag.js) - Google Analytics