由於工作需要,從網上下載了一個壓縮組件--DotNetZip,使用感覺良好,但是目錄中有中文名稱的檔案時,就會出現問題,要麼名稱顯示不全,要麼就顯示若干個問號,很是令人苦惱!!
沒辦法,只好自己動手解決問題啦,一步步的跟蹤定位,最後找到ZipEntry類的WriterHeader方法,估計是寫檔案頭,檔案名稱應當寫在這裡,經過調試,發現這一行:
Code
/**//////////////////////////////////替換內容
byte[] x = System.Text.Encoding.GetEncoding("GB2312").GetBytes(FileName);
Int16 filenameLength = (Int16)x.Length;
/**/////////////////////////////////被替換內容
// filename length (Int16)
//Int16 filenameLength = (Int16)FileName.Length;
/**/////////////////////////////////
FileName.Length不論遇到一個漢字還是一個字母數字,都是返回1,而一個漢字卻佔兩個位元組,可能問題出在這兒,再進一步地跟蹤,果然發現問題
Code
1/**//////////////////////////替換內容
2for (j = 0; (j < x.Length) && (i + j < bytes.Length); j++)
3{
4 bytes[i + j] = x[j];
5 if (_Debug) System.Console.Write(" {0:X2}", bytes[i + j]);
6}
7if (_Debug) System.Console.WriteLine();
8
9/**/////////////////////////被替換內容
10
11//for (j = 0; (j < c.Length) && (i + j < bytes.Length); j++)
12//{
13// bytes[i + j] = System.BitConverter.GetBytes(c[j])[0];
14// if (_Debug) System.Console.Write(" {0:X2}", bytes[i + j]);
15//}
16//if (_Debug) System.Console.WriteLine();
17/**/////////////////////////
程式大意是將檔案名稱轉換為字元數組,再將字元數組壓縮為位元組數組,而一個字元中只有一個漢字,壓縮完之後只有一個位元組,而一個位元組是無法表示漢字的,所以,我先採用GetBytes直接產生位元組數組,獲得字串的真實長度[即漢字為2,字母數字為1],然後將位元組數組逐個拷至目的位元組數組,編譯運行,中文名稱果然順利顯示出來了!!!
問題好象是解決了,可是當解壓時,卻傻眼了,都是些亂碼.不過有了上次的調試經驗,不需要辛苦跟蹤了,知道問題出在讀Header的地方,果然在ZipEntry類中,有ReadHeader方法,設斷點,調試,最後定位於Shared類中的StringFromBuffer方法
Code
1/**//////////////////////////替換內容
2string str2 = System.Text.Encoding.GetEncoding("GB2312").GetString(buf, start, maxlength);
3return str2;
4
5/**/////////////////////////被替換內容
6//int i;
7//char[] c = new char[maxlength];
8//for (i = 0; (i < maxlength) && (i < buf.Length) && (buf[i] != 0); i++)
9//{
10// c[i] = (char)buf[i]; // System.BitConverter.ToChar(buf, start+i*2);
11//}
12//string s = new System.String(c, 0, i);
13//return s;
14/**/////////////////////////
這個方法大意是,將位元組數組逐個轉換為字元數組,將漢字的編碼拆成兩個字元,這很明顯會造成亂碼,既然編碼採用GetBytes,那麼解碼也就用反的,GetString就行了,編譯運行,大功告成!!
原始碼下載:http://files.cnblogs.com/redleaf1995/DotNetZip.rar