標籤:java代碼 output war 技術 檔案亂碼 檔案開啟 static win bug
系統:win7 (格式:中文(簡體,中國))
工具:Eclipse (預設編碼utf-8)
服務兩個:【restful介面】 和 【服務*** server】。
情境:【服務*** server】多次調用【restful介面】,每次【restful介面】會返回一個產生好的csv檔案內容。【服務*** server】將每次【restful介面】返回的csv內容儲存成一個csv檔案。並將產生的多個csv檔案打包成一個zip壓縮包。
【restful介面】:根據一組資料產生csv檔案
1. java代碼產生csv檔案,檔案輸出資料流編碼設定為"UTF-8"時,產生的csv檔案開啟後,中文亂碼。
2. 將檔案輸出資料流編碼設定為"GB2312",產生的csv檔案開啟後,中文沒有亂碼。
java代碼如下:
/** * 產生.csv格式檔案 */ public static boolean createCsvFile(List<Object[]> rows, String filePath, String fileName) { // 標記檔案產生是否成功 boolean flag = true; // 檔案輸出資料流 BufferedWriter fileOutputStream = null; try { // 含檔案名稱的全路徑 String fullPath = filePath + File.separator + fileName + Constants.SUFFIX_CSV; File file = new File(fullPath); if (!file.getParentFile().exists()) { // 如果父目錄不存在,建立父目錄 file.getParentFile().mkdirs(); } if (file.exists()) { // 如果已存在,刪除舊檔案 file.delete(); } file = new File(fullPath); file.createNewFile(); // 格式化浮點數據 NumberFormat formatter = NumberFormat.getNumberInstance(); formatter.setMaximumFractionDigits(10); // 設定最大小數位為10 // 格式化日期資料 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); // 執行個體化檔案輸出資料流 fileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "GB2312"), 1024); // 遍曆輸出每行 Iterator<Object[]> ite = rows.iterator(); while (ite.hasNext()) { Object[] rowData = (Object[]) ite.next(); for (int i = 0; i < rowData.length; i++) { Object obj = rowData[i]; // 當前欄位 // 格式化資料 String field = ""; if (null != obj) { if (obj.getClass() == String.class) { // 如果是字串 field = (String) obj; } else if (obj.getClass() == Double.class || obj.getClass() == Float.class) { // 如果是浮點型 field = formatter.format(obj); // 格式化浮點數,使浮點數不以科學計數法輸出 } else if (obj.getClass() == Integer.class || obj.getClass() == Long.class || obj.getClass() == Short.class || obj.getClass() == Byte.class) { // 如果是整形 field += obj; } else if (obj.getClass() == Date.class) { // 如果是日期類型 field = sdf.format(obj); } } else { field = " "; // null時給一個空格佔位 } // 拼接所有欄位為一行資料 if (i < rowData.length - 1) { // 不是最後一個元素 fileOutputStream.write("\"" + field + "\"" + ","); } else { // 是最後一個元素 fileOutputStream.write("\"" + field + "\""); } } // 建立一個新行 if (ite.hasNext()) { fileOutputStream.newLine(); } } fileOutputStream.flush(); } catch (Exception e) { flag = false; log.error("產生資料檔案是報錯!", e); e.printStackTrace(); } finally { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return flag; }View Code
【服務*** server】:通過restful介面來擷取csv檔案內容,並儲存成csv檔案
1. 【restful介面】通過流讀取用"GB2312"編碼產生的csv檔案,此時資料流的編碼是個仍舊是"GB2312".
2. 【服務*** server】通過【restful介面】來擷取csv檔案內容,因為 服務【服務*** server】的預設編碼是"iso-8859-1"。此時接受到的csv內容編碼由"GB2312"被強轉成了"iso-8859-1". 此時,Eclipse中debug看到的csv內容中文是亂碼的。
3. 【服務*** server】側,重新編碼csv內容,使漢字不再亂碼。
// content是接收到的csv內容的字串(String類型)
content = convertEncodingFormat(content, "iso-8859-1", "GB2312");
4. 【服務*** server】如果想在本地將接收到的csv檔案儲存起來,並且中文可見。還需要設定輸出資料流編碼設定為"GB2312"。
/** * 把內容寫入檔案csv,因為csv使用GB2312編碼,需要單獨處理 */ @SuppressWarnings("resource") public static boolean createCsvFileWithContent(String parentPath, String fileName, String contentStr) { // 標記檔案產生是否成功 boolean flag = true; // 拼接檔案完整路徑 String fullPath = parentPath + File.separator + fileName; // 檔案輸出資料流 BufferedWriter fileOutputStream = null; // 產生json格式檔案 try { // File file = new File(fullPath); if (!file.getParentFile().exists()) { // 如果父目錄不存在,建立父目錄 file.getParentFile().mkdirs(); } if (file.exists()) { // 如果已存在,刪除舊檔案 file.delete(); } file = new File(fullPath); file.createNewFile(); // 執行個體化檔案輸出資料流 fileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "GB2312"), 1024); fileOutputStream.write(contentStr); fileOutputStream.flush(); } catch (Exception e) { flag = false; log.error("產生資料檔案是報錯!", e); e.printStackTrace(); } // 返回是否成功的標記 return flag; }View Code
至此結束。
記一次java產生csv檔案亂碼的解決過程 (GB2312編碼)