摘要:之前一段時間排查一個應用在中文目錄下無法啟動的問題,查過一個的處理的坑。這里記錄一下里面對中的中文處理的坑。只能說在用到的時候,盡量不要使用中文的吧。
之前一段時間排查一個應用在中文目錄下無法啟動的問題,查過一個 Equinox 的 Manifest 處理的坑。今天,一個同事在寫 Equinox 插件的時候也遇到了類似的問題。這里記錄一下 Equinox 里面對 Manifest 中的中文處理的坑。
問題描述先來看一段代碼:
package manifest; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.jar.Manifest; import org.eclipse.osgi.util.ManifestElement; import org.osgi.framework.BundleException; public class Test { private static String chineseString = "你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界你好,世界"; public static void main(String[] args) throws IOException, BundleException { File manifestFile = createManifest(); // 使用 ManifestElement 讀取 Mapheader = new HashMap<>(); ManifestElement.parseBundleManifest(new FileInputStream(manifestFile), header); System.out.println(header.get("Test-Headers")); } private static File createManifest() throws IOException { Manifest manifest = new Manifest(); manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); // 創(chuàng)建一個帶有中文的 Header,MANIFEST.MF 的一行的最大長度是 72 字節(jié),中文在這里會被階段 manifest.getMainAttributes().putValue("Test-Headers", chineseString); File file = new File("MANIFEST.MF"); if (!file.exists()) { file.createNewFile(); } OutputStream outputStream = new FileOutputStream(file); manifest.write(outputStream); outputStream.flush(); outputStream.close(); return file; } }
這一段代碼雖然比較長,但是實際上的內容其實不多,主要做了這幾步:
創(chuàng)建一個內容帶有中文的 MANIFEST.MF 文件。
寫入 MANIFEST.MF 文件到磁盤上。
用 Equinox 的 ManifestElement 來讀取 MANFIEST.MF。
輸出剛才的帶有中文的 Header
上面的這段代碼在我本地的執(zhí)行結果如下:
你好,世界你好,世界你好,世界你好,??界你好,世界你好,世界你好,世界你好,世界你??,世界你好,世界你好,世界你好,世界
大家可以看到,中間有幾個地方出現(xiàn)了亂碼,同樣的代碼,如果用標準的 JDK 的方式來讀取,是不會出現(xiàn)這種情況,為什么呢?
原因首先,我們知道 UTF-8 的中文是占據(jù)了三個字節(jié),而 MANIFEST.MF 文件一行的最大長度是 72 個字節(jié),也就是說,如果你的 MANIFEST.MF 中含有中文,那么這個中文的三個字節(jié)可能會被截斷,出現(xiàn)一部分在上面一行,一部分在下面一行的情況。上面的 MANIFEST.MF 文件就出現(xiàn)了這種情況,可以 cat 這個文件來看一下:
[~/Desktop/test]$ cat MANIFEST.MF Manifest-Version: 1.0 Test-Headers: 你好,世界你好,世界你好,世界你好,? ?界你好,世界你好,世界你好,世界你好,世界你? ?,世界你好,世界你好,世界你好,世界
不過,即使這樣寫入了,如果讀取的時候完全按照字節(jié)來讀取的話,那也應該沒有問題。但是,Equinox 比較特立獨行,看下 Equinox 讀取 Manifest 的關鍵代碼:
作死的 Equinox 將一行讀取出來以后直接轉成了一個 string,而 byte 在轉 string 的時候,如果遇到無法轉的字節(jié)的話,會用 ? 來替代,于是就出現(xiàn)了上面的情況。(關于 ?,可以看 http://en.wikipedia.org/wiki/Specials_(Unicode_block))
解決方法這個問題除非 Equinox 修復了此 Bug,否則是無解的。只能說在用到 Equinox 的時候,盡量不要使用中文的 Header 吧。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/64266.html
摘要:使用文件與以下好處安全。包作為內嵌在平臺內部處理的標準,能夠在各種平臺上直接使用命令詳解創(chuàng)建文件該命令沒有顯示壓縮過程,執(zhí)行結果是將當前路徑下的路徑下的全部內容生成一個文件。使用如下命令即可將清單文件中的對提取到文件中。 JAR,Java Archive File,Java檔案文件。JAR文件是一種壓縮文件,與ZIP壓縮文件兼容,通常稱為JAR包。JAR文件中默認包含了一個名為META...
摘要:簡介是命令的一個參數(shù)。參數(shù)可以用于指定一個包,并且對該包有個要求這個包的文件必須指定項。重點就在方法,也就是我們今天的標題。和類加載器比較類加載器也可以實現(xiàn)運行時修改代碼。使用能讓修改字節(jié)碼這個動作化于無形,對業(yè)務透明,減少侵入性。 簡介 java agent是java命令的一個參數(shù)。參數(shù) javaagent 可以用于指定一個 jar 包,并且對該 java 包有2個要求: 這個 j...
閱讀 3247·2021-11-23 09:51
閱讀 1634·2021-11-22 09:34
閱讀 2921·2021-10-27 14:15
閱讀 2401·2021-10-12 10:17
閱讀 2012·2021-10-12 10:12
閱讀 1031·2021-09-27 14:00
閱讀 2075·2021-09-22 15:19
閱讀 1102·2019-08-30 10:51