歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Unix知識 >> 關於Unix

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

一、問題的出現: 有一天有人發了個.zip的文件給我。我unzip它,卻發現中文名的文件解出來文件名是錯的。 二、上網尋找問題答案: 有網友告訴我,是因為winzip用某種OEM方式修改文件名所致(後來證明這個說法是錯的), 要用另外一個某某更強大的zip並關閉OEM
  一、問題的出現:
  有一天有人發了個.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