用java多執行緒實現“百度翻譯介面API快速翻譯”
阿新 • • 發佈:2019-01-06
不知道為啥,突然開始想寫部落格,可能是想找個地方寫點東西,煽情文藝的咱寫不了,就寫技術貼好了。不當之處,還希望同志們多多指教,不勝感激。
API準備:自己先到百度去申請一個百度翻譯API,話說百度翻譯還是可以的,每個月200W字元的免費翻譯,不做商業的基本夠用了,感謝百度。百度不僅提供了API,還提供了各個程式語言的demo,我們這邊使用java語言版。自己可以試著玩一玩。
我要做的是用百度翻譯來幫我翻譯大概有十幾個英文文件,長短不一,十幾KB到一百多KB不等,總的在600KB左右。
經過試驗,單執行緒跑了一個小時左右,而多執行緒大概跑了12分鐘(最後就剩下那個最長的文件在跑,長板效應!!不是因為它的話時間會縮短很多!!!)。
以前感覺多執行緒、平行計算老牛逼了,其實實現後發現這實現起來也太簡單了點。其實就是把需要相同重複執行的程式碼封裝到run()方法裡面。多執行緒有個很基本的點就是:子執行緒的執行不影響主執行緒的執行,想明白這點就差不多了。
//extends Thread 就是繼承多執行緒類 public class MultiTranslate extends Thread{ private static final String APP_ID = "你的API_ID"; private static final String SECURITY_KEY = "API密匙"; //通過定義類屬性,來傳遞變數,Thread類的run()方法不能帶引數 String filename=""; public MultiTranslate(String filename) { super(); this.filename = filename; } @Override public void run() { String ThreadName=Thread.currentThread().getName(); //呼叫百度翻譯API TransApi api = new TransApi(APP_ID, SECURITY_KEY); //獲得待翻譯文件路徑,文件為eclipse下專案Source檔案,filename為檔名 String url = newMain.class.getClassLoader().getResource(filename).getPath(); try { String newFile = URLDecoder.decode(url, "UTF-8"); BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(newFile), "utf-8")); String line = null; //翻譯完輸出到新文件,我給新文件名加了字首“ZH” FileOutputStream out = new FileOutputStream(new File("ZH"+filename),true); //正則匹配,百度翻譯完傳回來一個json形式,包括很多內容,我只取翻譯結果 String questionRegex = "\"dst\":\"(.*)\""; Pattern pattern = Pattern.compile(questionRegex); while ((line = reader.readLine()) != null) { String[] words=line.split(" "); StringBuilder NewLine=new StringBuilder(); for(int i=0;i<words.length;i++){ //呼叫介面,進行翻譯 String get = new String(api.getTransResult(words[i], "auto", "zh")); Matcher matcher = pattern.matcher(get); while (matcher.find()) { String getword = matcher.group(1); //API返回的是Unicode編碼,import org.apache.commons.lang.StringEscapeUtils, //呼叫StringEscapeUtils.unescapeJava()方法可解決編碼問題 String newgetword = StringEscapeUtils.unescapeJava(getword); NewLine.append(newgetword+" "); } } String newline=NewLine.toString().trim()+"\n"; System.out.println(filename+" "+ThreadName+" newline="+newline); out.write(newline.getBytes("utf-8")); } out.close(); reader.close(); } catch (Exception e) { throw new RuntimeException("文件載入失敗!"); } } public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException { String path="xxx"; ArrayList<String> filenameList=new ArrayList<String>(); filenameList=getAllFile(path); for (int i = 0; i < filenameList.size(); i++) { //對每個文件生成一個執行緒,for迴圈生成多個執行緒分別執行翻譯任務 Thread myThread=new MultiTranslate(filenameList.get(i)); //Thread會去執行run()方法 myThread.start(); //如果多加了join()方法會變成單執行緒效果,主執行緒會等待子執行緒執行完再繼續。 //myThread.join(); } } /** * 讀取某個資料夾下的所有檔案,包括子資料夾下的檔案 * * @param filepath * 資料夾的路徑 * @return * @throws FileNotFoundException * @throws IOException */ public static ArrayList<String> getAllFile(String filepath) throws FileNotFoundException, IOException { File file = new File(filepath); ArrayList<String> pathList=new ArrayList<String>(); File[] filelist = null; try { filelist = file.listFiles(); for (File onefile : filelist) { File readfile = new File(onefile.getPath()); if (readfile.isDirectory()) { getAllFile(onefile.getPath()); } else { String filename=getDocName(readfile.getPath()); pathList.add(filename); } } } catch (FileNotFoundException e) { throw new RuntimeException("getAllFile() Exception:" + e.getMessage()); } return pathList; } //取得文件標題 public static String getDocName(String path) { String[] temp = path.split("\\\\"); if (temp.length >= 1) { String strtemp = temp[temp.length - 1]; return strtemp.trim(); } return ""; } }
轉發請註明原文出處,謝謝。