IT Notes‎ > ‎Java‎ > ‎Java Language‎ > ‎《Java 解惑》笔记‎ > ‎Puzzle 17: Huh‎ > ‎

转化Java源代码为Unicode转义字符的工具

为了记录Puzzle 17的笔记, 需要写一个程序, 完成如下功能:
  1. 读入原始的程序文件. 如*.java文件.
  2. 将源文件中所有字符用Unicode转义字符替换, 包括不可见的换行符等.
  3. 输出替换后的文本, 按要求备份或不备份转化前的代码。
以下为该类的全文:
package hello;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 完成字符串到Unicode转义字符的转化s
 * @author iridium
 */
public class UnicodeConvertor {

    public static void main(String[] args) {
        UnicodeConvertor uc = new UnicodeConvertor();
        uc.convertToUnicode(new File("/home/iridium/Documents/He.java"));
    }

    public static String strToUnicode(String str, int width) {
        StringBuffer sb = new StringBuffer();
        char[] array = str.toCharArray();
        int count = 0;
        for (char c : array) {
            String s = Integer.toHexString(c);
            if (s.length() < 4) {
                s = "0000".substring(s.length()) + s;
            }
            sb.append("\\u").append(s);
            count++;
            if (count % width == 0) {
                sb.append("\n");
                count = 0;
            }
        }
        return sb.toString();
    }

    public static String strToUnicode(String str) {
        return strToUnicode(str, 10);
    }

    public static String fileToString(File file) {
        FileReader fr = null;
        StringBuffer sb = new StringBuffer();

        try {

            fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            String s = br.readLine();
            while (s != null) {
                sb.append(s);
                s = br.readLine();
            }
            return sb.toString();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(UnicodeConvertor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(UnicodeConvertor.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fr.close();
            } catch (IOException ex) {
                Logger.getLogger(UnicodeConvertor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * invoke converToUnicode(File, boolean), as the second parameter is true default
     * @param file
     */
    public void convertToUnicode(File file) {
        this.convertToUnicode(file, true);
    }

    /**
     * convert content of a file to Unicode escapes
     * @param file source file to be converted
     * @param bak if it equals true, a backup file will be kept
     */
    public void convertToUnicode(File file, boolean bak) {
        try {
            String name = file.getCanonicalPath();

            String nameBak = name + ".bak";
            file.renameTo(new File(nameBak));

            File distFile = new File(name);
            String orginalSrc = this.fileToString(new File(nameBak));
            String unicodeStr = this.strToUnicode(orginalSrc, 1000);
            FileWriter fw = new FileWriter(distFile);
            PrintWriter pw = new PrintWriter(fw);
            pw.write(unicodeStr);
            pw.close();

            if (!bak) {
                file.delete();
            }
        } catch (IOException ex) {
            Logger.getLogger(UnicodeConvertor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

有很大的优化空间。
已知的问题:
  1. 文件输入输出没有cache方式。
  2. 代码可能被截断成不能用,目前先使所有的代码都输出成一行。


  1. 百度知道上有一个类似的记录,但不清楚它在说什么,貌似和我的做法基本两样,等有空的时候需要仔细看看他是怎么做的。

Comments