摘要:之前一段時(shí)間排查一個(gè)應(yīng)用在中文目錄下無(wú)法啟動(dòng)的問(wèn)題,查過(guò)一個(gè)的處理的坑。這里記錄一下里面對(duì)中的中文處理的坑。只能說(shuō)在用到的時(shí)候,盡量不要使用中文的吧。
之前一段時(shí)間排查一個(gè)應(yīng)用在中文目錄下無(wú)法啟動(dòng)的問(wèn)題,查過(guò)一個(gè) Equinox 的 Manifest 處理的坑。今天,一個(gè)同事在寫(xiě) Equinox 插件的時(shí)候也遇到了類似的問(wèn)題。這里記錄一下 Equinox 里面對(duì) Manifest 中的中文處理的坑。
問(wèn)題描述先來(lái)看一段代碼:
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)建一個(gè)帶有中文的 Header,MANIFEST.MF 的一行的最大長(zhǎng)度是 72 字節(jié),中文在這里會(huì)被階段 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; } }
這一段代碼雖然比較長(zhǎng),但是實(shí)際上的內(nèi)容其實(shí)不多,主要做了這幾步:
創(chuàng)建一個(gè)內(nèi)容帶有中文的 MANIFEST.MF 文件。
寫(xiě)入 MANIFEST.MF 文件到磁盤上。
用 Equinox 的 ManifestElement 來(lái)讀取 MANFIEST.MF。
輸出剛才的帶有中文的 Header
上面的這段代碼在我本地的執(zhí)行結(jié)果如下:
你好,世界你好,世界你好,世界你好,??界你好,世界你好,世界你好,世界你好,世界你??,世界你好,世界你好,世界你好,世界
大家可以看到,中間有幾個(gè)地方出現(xiàn)了亂碼,同樣的代碼,如果用標(biāo)準(zhǔn)的 JDK 的方式來(lái)讀取,是不會(huì)出現(xiàn)這種情況,為什么呢?
原因首先,我們知道 UTF-8 的中文是占據(jù)了三個(gè)字節(jié),而 MANIFEST.MF 文件一行的最大長(zhǎng)度是 72 個(gè)字節(jié),也就是說(shuō),如果你的 MANIFEST.MF 中含有中文,那么這個(gè)中文的三個(gè)字節(jié)可能會(huì)被截?cái)啵霈F(xiàn)一部分在上面一行,一部分在下面一行的情況。上面的 MANIFEST.MF 文件就出現(xiàn)了這種情況,可以 cat 這個(gè)文件來(lái)看一下:
[~/Desktop/test]$ cat MANIFEST.MF Manifest-Version: 1.0 Test-Headers: 你好,世界你好,世界你好,世界你好,? ?界你好,世界你好,世界你好,世界你好,世界你? ?,世界你好,世界你好,世界你好,世界
不過(guò),即使這樣寫(xiě)入了,如果讀取的時(shí)候完全按照字節(jié)來(lái)讀取的話,那也應(yīng)該沒(méi)有問(wèn)題。但是,Equinox 比較特立獨(dú)行,看下 Equinox 讀取 Manifest 的關(guān)鍵代碼:
作死的 Equinox 將一行讀取出來(lái)以后直接轉(zhuǎn)成了一個(gè) string,而 byte 在轉(zhuǎn) string 的時(shí)候,如果遇到無(wú)法轉(zhuǎn)的字節(jié)的話,會(huì)用 ? 來(lái)替代,于是就出現(xiàn)了上面的情況。(關(guān)于 ?,可以看 http://en.wikipedia.org/wiki/Specials_(Unicode_block))
解決方法這個(gè)問(wèn)題除非 Equinox 修復(fù)了此 Bug,否則是無(wú)解的。只能說(shuō)在用到 Equinox 的時(shí)候,盡量不要使用中文的 Header 吧。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/64266.html
摘要:使用文件與以下好處安全。包作為內(nèi)嵌在平臺(tái)內(nèi)部處理的標(biāo)準(zhǔn),能夠在各種平臺(tái)上直接使用命令詳解創(chuàng)建文件該命令沒(méi)有顯示壓縮過(guò)程,執(zhí)行結(jié)果是將當(dāng)前路徑下的路徑下的全部?jī)?nèi)容生成一個(gè)文件。使用如下命令即可將清單文件中的對(duì)提取到文件中。 JAR,Java Archive File,Java檔案文件。JAR文件是一種壓縮文件,與ZIP壓縮文件兼容,通常稱為JAR包。JAR文件中默認(rèn)包含了一個(gè)名為META...
摘要:簡(jiǎn)介是命令的一個(gè)參數(shù)。參數(shù)可以用于指定一個(gè)包,并且對(duì)該包有個(gè)要求這個(gè)包的文件必須指定項(xiàng)。重點(diǎn)就在方法,也就是我們今天的標(biāo)題。和類加載器比較類加載器也可以實(shí)現(xiàn)運(yùn)行時(shí)修改代碼。使用能讓修改字節(jié)碼這個(gè)動(dòng)作化于無(wú)形,對(duì)業(yè)務(wù)透明,減少侵入性。 簡(jiǎn)介 java agent是java命令的一個(gè)參數(shù)。參數(shù) javaagent 可以用于指定一個(gè) jar 包,并且對(duì)該 java 包有2個(gè)要求: 這個(gè) j...
閱讀 3194·2021-11-23 09:51
閱讀 1534·2021-11-22 09:34
閱讀 2844·2021-10-27 14:15
閱讀 2290·2021-10-12 10:17
閱讀 1895·2021-10-12 10:12
閱讀 956·2021-09-27 14:00
閱讀 2006·2021-09-22 15:19
閱讀 1041·2019-08-30 10:51