`
xxjkcyt
  • 浏览: 5714 次
  • 性别: 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编程语言开发的应用,主要功能是进行文件编码的转换。在IT领域,文件编码是至关重要的,不同的编码格式适用于不同的语言和平台,例如ASCII、UTF-8、GBK等。这...

    java 文件编码转换

    标题"java 文件编码转换"指的是使用Java来解决文件编码问题,而描述中提到的"提供一个jar包和一个java文件"则暗示了我们可以通过这两个文件实现这个功能。 首先,`chardet.jar`可能是一个字符集检测库,用于自动...

    java文件编码转换

    本篇文章将深入探讨“Java文件编码转换”这一主题,以及如何利用Java进行文件编码的转换,解决在处理文本文件时可能出现的乱码问题。 首先,我们要理解什么是字符编码。字符编码是用来表示文本的一种规则,常见的有...

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

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

    文件编码转换工具

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

    文件任意编码转换工具 ExecuteConvertFile

    总结来说,"ExecuteConvertFile"是一款强大的文件编码转换工具,它结合了自动检测和转换的功能,有效地解决了跨编码环境的数据处理问题。无论是普通用户还是专业开发者,都能从中受益。通过深入研究其工作原理和源...

    JAVA文件编码转换和实现目录与文件打开

    总的来说,Java提供了强大的工具来处理文件编码转换和文件操作,包括`java.io`和`java.nio`包中的类,以及AWT和Swing库来构建图形用户界面。理解这些概念对于开发跨平台的应用程序至关重要。在实际项目中,你可能...

    JAVA文件编码转换

    ### JAVA文件编码转换 #### 知识点概览 1. **文件编码概念与重要性** 2. **Java中的字符集处理** 3. **文件读写操作** 4. **使用NIO进行文件编码转换** 5. **异常处理** #### 文件编码概念与重要性 在计算机科学...

    JAVA 转换字符编码工具

    总结来说,`JAVA 转换字符编码工具`是利用Java语言实现的字符编码转换程序,通过提供的源代码文件可以学习到如何在Java中进行编码转换操作,以及如何设计和测试这样的工具。这个工具对于处理多语言环境或跨平台通信...

    java文件的编码转换

    总之,Java提供了一系列工具来处理文件编码转换,理解这些工具的使用方法对于处理跨平台或多语言环境的项目至关重要。通过上述步骤,你可以编写一个简单的Java程序,有效地将GBK编码的Java源代码转换为UTF-8,从而...

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

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

    swt文件编码转换工具

    SWT文件编码转换工具是一款基于Java开发的实用程序,用于帮助用户处理不同字符编码之间的转换问题。SWT,全称Standard Widget Toolkit,是Eclipse项目的一部分,它提供了一套跨平台的用户界面组件,使得开发者可以...

    java项目编码转换工具类

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

    java各文件转换应用源码

    总的来说,这个Java文件转换应用源码项目是一个全面的文件处理工具,涵盖了多种常见的文件格式转换需求。它展示了如何利用Java和其第三方库来处理复杂的文件操作,对于提升Java开发者的文件处理技能和实战经验具有很...

    java源文件编码转换工具加源码(自动检测源文件编码类型)

    Java源文件编码转换工具是一种实用程序,用于解决在处理不同编码格式的源代码时遇到的问题。在软件开发中,源代码文件可能以多种编码格式存储,例如GBK或UTF-8,这可能导致在合并代码或在不同环境中运行时出现乱码...

    文件编码转换器源码

    在这个特定的“文件编码转换器源码”中,主要涉及了从GB2312编码到UTF-8编码的转换。GB2312,全称为《信息交换用汉字编码字符集·基本集》,是中国大陆早期广泛使用的简体中文字符编码标准。而UTF-8则是Unicode ...

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

    这个工具的源码对于学习Java文件操作、字符编码以及GUI编程具有很高的参考价值。通过阅读和理解源码,开发者可以深入掌握Java的I/O机制以及如何设计和实现一个实用的桌面应用。同时,这也是一个很好的实践案例,展示...

    java批量转换文件编码

    本话题主要关注如何使用Java进行批量文件编码转换,特别是从一种编码(如GBK)转换到另一种编码(如UTF-8)。以下是对这个主题的详细阐述: 首先,我们需要理解什么是文件编码。文件编码是存储和显示文本内容的规则...

Global site tag (gtag.js) - Google Analytics