背景:由於之前開發插件的java代碼里,中文注釋和顯示信息都是直接寫在java代碼中,現在需要將其中的需要做國際化的中文資源提取出來,放到properties文件里,所以寫了一個小工具。
思想:應用了狀態機模式編程,定義正常狀態(NormalState),引號內狀態(QuotState),塊注釋狀態(BlockNote),行注釋狀態(LineNote),四個狀態類,定義一個流程控制類(Process),一個數據模型類(DataModel),還有一個Main類(Main)。
廢話不多說,上代碼。
數據模型類(DataModel)
import java.io.BufferedReader; import java.io.PrintWriter; public class DataModel { private State state; private BufferedReader reader; private String line; private int from; private PrintWriter output; public DataModel(State state, BufferedReader reader, String line, int from, PrintWriter output) { super(); this.state = state; this.reader = reader; this.line = line; this.from = from; this.output = output; } public State getState() { return state; } public void setState(State state) { this.state = state; } public BufferedReader getReader() { return reader; } public void setReader(BufferedReader reader) { this.reader = reader; } public String getLine() { return line; } public void setLine(String line) { this.line = line; } public int getFrom() { return from; } public void setFrom(int from) { this.from = from; } public PrintWriter getOutput() { return output; } public void setOutput(PrintWriter output) { this.output = output; } }
狀態類的基類:
import java.io.BufferedReader; import java.io.PrintWriter; public abstract class State { public abstract void handle(BufferedReader reader,String line,int from,PrintWriter output); }
四個狀態子類,其中行注釋類不需要做處理。
package src; import java.io.BufferedReader; import java.io.PrintWriter; public class NormalState extends State { public static final NormalState normal = new NormalState(); @Override public void handle(BufferedReader reader, String line, int from, PrintWriter output) { // TODO Auto-generated method stub for (int k = from; k < line.length(); k++) { char now = line.charAt(k); if ((now == '"' && k == 0) || (now == '"' && k > 0 && line.charAt(k - 1) != '\\')) { Process.queue.add(new DataModel(QuotState.quotState, reader, line, k + 1, output)); break; } else if ('/' == now && k < line.length() - 1 && ('/' == line.charAt(k + 1))) { break;// go back to process's excute } else if ('/' == now && k < line.length() - 1 && ('*' == line.charAt(k + 1))) { Process.queue.add(new DataModel(BlockNote.blockNote, reader, line, k + 2, output)); break; } } } }
package src; import java.io.BufferedReader; import java.io.PrintWriter; public class QuotState extends State { public static final QuotState quotState = new QuotState(); public static int keynum = 0; @Override public void handle(BufferedReader reader, String line, int from, PrintWriter output) { // TODO Auto-generated method stub int beginIndex = from, endIndex = from, k = from; boolean out = false; for (k = from; k < line.length(); k++) { char now = line.charAt(k); if ((now == '"' && k == 0) || (now == '"' && k > 0 && line.charAt(k - 1) != '\\')) { Process.queue.add(new DataModel(NormalState.normal, reader, line, k + 1, output)); break; } else if (line.substring(k, k + 1).getBytes().length > 1) { for (; k < line.length(); k++) { if (line.charAt(k) == '"' && line.charAt(k - 1) != '\\') { endIndex = k; break; } } System.out.println("key: " + keynum++ + " " + line.substring(beginIndex, endIndex)); output.write(line.substring(beginIndex, endIndex) + "\n"); out = true; break; } } if (out) { Process.queue.add(new DataModel(NormalState.normal, reader, line, k + 1, output)); } } }
package src; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; class BlockNote extends State { public static final BlockNote blockNote = new BlockNote(); @Override public void handle(BufferedReader reader, String line, int from, PrintWriter output) { // TODO Auto-generated method stub boolean out = false; int k = from; for (k = from; k < line.length(); k++) { char now = line.charAt(k); if ('*' == now && k < line.length() - 1 && ('/' == line.charAt(k + 1))) { out = true; break; } } try { label: while (!out && (line = reader.readLine()) != null) { for (k = 0; k < line.length(); k++) { char now2 = line.charAt(k); if ('*' == now2 && k < line.length() - 1 && ('/' == line.charAt(k + 1))) { out = true; break label; } } } if (out) { Process.queue.add(new DataModel(NormalState.normal, reader, line, k + 2, output)); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
import java.io.BufferedReader; import java.io.PrintWriter; public class LineNote extends State{ @Override public void handle(BufferedReader reader, String line, int from,PrintWriter output) { // TODO Auto-generated method stub } }
處理控制類
package src; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class Process { public static Queue<DataModel> queue = new ConcurrentLinkedQueue<DataModel>(); private PrintWriter output = null; private String charset = null; public Process(PrintWriter output, String charset) { this.output = output; this.charset = charset; } public void readTxt(File tempFile) throws IOException { System.out.println("#" + tempFile.getName() + "\n"); output.write("#" + tempFile.getName() + "\n"); BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(tempFile), charset)); String tempString = ""; while ((tempString = reader.readLine()) != null) { queue.add(new DataModel(NormalState.normal, reader, tempString, 0, output)); while (queue.size() > 0) { DataModel dm = queue.remove(); dm.getState().handle(dm.getReader(), dm.getLine(), dm.getFrom(), dm.getOutput()); } } reader.close(); } public void readDir(String folder) throws IOException { File dir = new File(folder); // PrintWriter output = new PrintWriter(new FileWriter(new // File(outFile))); if (dir.isDirectory()) { System.out.println("#Dir#" + dir.getName() + "\n"); output.write("#Dir#" + dir.getName() + "\n"); String[] children = dir.list(); for (int i = 0; i < children.length; i++) { File tempFile = new File(dir, children[i]); if (tempFile.isDirectory()) readDir(tempFile.getName()); else { readTxt(tempFile); } } } } }
最后就是含有main方法的調用了。
package src; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class Main { public static String outFile = "F:/tiqu.properties"; public static String inFolder = "F:/src"; public static String charset = "gbk"; public static void main(String[] args) throws IOException { PrintWriter output = new PrintWriter(new FileWriter(new File(outFile))); Process process = new Process(output, charset); process.readDir(inFolder); output.close(); } }