歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

正確解壓包含中文文件名Winzip壓縮包

  一、問題的出現:   有一天有人發了個.zip的文件給我。我unzip它,卻發現中文名的文件解出來文件名是錯的。     二、上網尋找問題答案:   有網友告訴我,是因為WinZip用某種OEM方式修改文件名所致(後來證明這個說法是錯的), 要用另外一個某某更強大的zip並關閉OEM方式再壓縮才行。 但我想我們不應讓別人必須用某某個軟件來將就Unzip。     三、臨時解決問題:*本文所提供的方法是臨時性的解決辦法*   1. 到底發生了什麼問題?   ---------------------------   實驗1:在Linux下用zip壓縮兩個中文名文件並命名為1.zip,   結果1:在windows98下用Winzip打開中文件名沒問題。     實驗2: 在windows98下用Winzip壓縮相同的兩個中文名文件並命名為2.zip,   結果2:在Linux下用Unzip打開中文名出來的完全不對,但長度一致。     實驗3: 用二進制查看器比較兩個壓縮文件(1.zip,2.zip),   結果3:發現兩個壓縮文件中的文件名二進制編碼是完全一樣的。     實驗4: Unzip比較兩個壓縮文件的信息   結果4: 除文件名不同以外,就是類型(type)不同,一個是Unix,一個是fat。     結論:   winzip存文件名的方法與Unzip完全相同,   問題在Unzip中,它將類型為fat的壓縮文件中的文件名作了另外的解釋。     2.解決問題的方法   ***************************************   *修改Unzip讓它對文件名不作另外的解釋。*   ***************************************   找呀找......,終於找到了(我是通過學習了emacs及etags來找的)   ==============================================================================   在 Unzip-5.42 源文件包中的文件 unzpriv.h 約第 2396行上下   ==============================================================================   /* Convert filename (and file comment string) into "internal" charset.   * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)   * codepage when made on   * -> DOS (this includes 16-bit Windows 3.1) (FS_FAT_)   * -> OS/2 (FS_HPFS_)   * -> Win95/WinNT with Nico Mak's WinZip (FS_NTFS_ && hostver == "5.0")   * EXCEPTIONS:   * PKZIP for Windows 2.5 and 2.6 flag their entries as "FS_FAT_", but the   * filename stored in the local header is coded in Windows ANSI (ISO 8859-1).   * Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the   * filenames stored in BOTH the local and the central header are coded   * in the local system's codepage (usually ANSI codings like ISO 8859-1).   *   * All other ports are assumed to code zip entry filenames in ISO 8859-1.   */   #ifndef Ext_ASCII_TO_Native   # define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \   if (((hostnum) == FS_FAT_ && \   !(((islochdr) (isuxatt)) && \   (hostver) >= 25 && (hostver) <= 26)) \   (hostnum) == FS_HPFS_ \   ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \   _OEM_INTERN((string)); \   } else { \   _ISO_INTERN((string)); \   }   #endif   =============================================================================   *******************************************   *臨時修正的方法:全部都用函數_ISO_INTERN()*   *******************************************   修改如下:   =============================================================================   #ifndef Ext_ASCII_TO_Native   # define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \   /* if (((hostnum) == FS_FAT_ && \   * !(((islochdr) (isuxatt)) && \   * (hostver) >= 25 && (hostver) <= 26)) \   * (hostnum) == FS_HPFS_ \   * ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \   * _OEM_INTERN((string)); \   * } else { \ */   _ISO_INTERN((string)); \   /* } */   #endif   ==============================================================================   編譯成功,試一試,正確認出winzip壓縮的中文名!!!   ==============================================================================     四、方法的局限性和臨時性:   ***************************************************************   *方法的缺點很明顯,不能正確支持那幾種作了特殊處理的文件名了!!!*   *所以請高手指教更優的方法!!! *   ***************************************************************




Copyright © Linux教程網 All Rights Reserved