ASZip文件库是开源的AS3版–Zip压缩算法,具体示例应用可见http:///p/aszip/。目前的最新版本是0.2版。最近在项目中需要用到该第三方类库来支持Flash对图片文件的批量打包上传。由于是外国友人写的,所以对中文命名的图片文件进行压缩时,就会报错,只能支持用非中文的命名的图片文件。

 
下面是我在作者原有代码的基础上做了些改进,使其能良好的支持中英文命名的文件,进而对文件打包压缩。
  1. /** 
  2. * This class lets you generate zip files in AS3 
  3. * AS3 implementation of the following PHP script : 
  4. * http://www.zend.com/zend/spotlight/creating-zip-files1.php?article=creating-zip-files1&kind=sl&id=274&open=1&anc=0&view=1 
  5. * @author Thibault Imbert () 
  6. * @usage Compression methods for the files : 
  7. * CompressionMethod.NONE = no compression is applied 
  8. * CompressionMethod.GZIP = native GZIP compression is applied 
  9. first parameter : compression method 
  10. * var myZip:ASZIP = new ASZIP ( CompressionMethod.GZIP ); 
  11. * @version 0.1 First release 
  12. * @version 0.2 ASZip.saveZIP method added 
  13. */ 
  14.   
  15. package org.aszip.zip 
  16.   
  17. import flash.accessibility.Accessibility; 
  18. import flash.utils.ByteArray; 
  19. import flash.utils.Endian; 
  20. import .URLRequest; 
  21. import .URLRequestHeader; 
  22. import .URLRequestMethod; 
  23. import .navigateToURL; 
  24. import org.aszip.saving.Method; 
  25. import org.aszip.compression.CompressionMethod; 
  26. import org.aszip.crc.CRC32; 
  27.   
  28. /** 
  29. * The ASZip class represents a Zip file 
  30. */ 
  31. public class ASZip 
  32.   
  33. /** 
  34. * The compressed data buffer 
  35. */ 
  36. private var compressedData:ByteArray; 
  37. /** 
  38. * The central directory 
  39. */ 
  40. private var centralDirectory:ByteArray; 
  41. /** 
  42. * The central index 
  43. */ 
  44. private var oldOffset:Number 
  45. /** 
  46. * Number of directories in the zip 
  47. */ 
  48. private var nbDirectory:Array; 
  49. /** 
  50. * The final zip stream 
  51. */ 
  52. private var output:ByteArray; 
  53. /** 
  54. * The compression method used 
  55. */ 
  56. private var compressionMethod:String; 
  57. /** 
  58. * The comment string 
  59. */ 
  60. private var comment:String; 
  61.   
  62. /** 
  63. * Lets you create a Zip file 
  64. * @param pCompression Compression method 
  65. * @example 
  66. * This example shows how to create a valid ZIP file : 
  67. * <div> 
  68. * <pre> 
  69. * var myZip:ASZip = new ASZip ( CompressionMethod.GZIP ); 
  70. * </pre> 
  71. * </div> 
  72. */ 
  73. public function ASZip ( pCompression:String='GZIP' ) 
  74.   
  75. compressedData = new ByteArray; 
  76. centralDirectory = new ByteArray; 
  77. output = new ByteArray; 
  78. nbDirectory = new Array 
  79. comment = new String;; 
  80. oldOffset = 0; 
  81. compressionMethod = pCompression; 
  82.   
  83. /** 
  84. * Lets you create a directory for the current Zip 
  85. * @param directoryName Name of the directory 
  86. * @example 
  87. * This example shows how to create a directory and subdirectory : 
  88. * <div> 
  89. * <pre> 
  90. * myZip.addDirectory ( "p_w_picpaths" ); 
  91. * myZip.addDirectory ( "p_w_picpaths/funk" ); 
  92. * </pre> 
  93. * </div> 
  94. */ 
  95. public function addDirectory ( directoryName:String ):void 
  96. directoryName = directoryName.split ('\\').join ('/'); 
  97.   
  98. var feedArrayRow:ByteArray = new ByteArray; 
  99. feedArrayRow.endian = Endian.LITTLE_ENDIAN; 
  100. feedArrayRow.writeUnsignedInt ( 0x04034b50 ); 
  101. feedArrayRow.writeShort ( 0x000a ); 
  102. feedArrayRow.writeShort ( 0x0000 ); 
  103. feedArrayRow.writeShort ( 0x0000 ); 
  104. feedArrayRow.writeUnsignedInt ( unixToDos ( new Date().getTime() ) ); 
  105.   
  106. feedArrayRow.writeUnsignedInt (0); 
  107. feedArrayRow.writeUnsignedInt (0); 
  108. feedArrayRow.writeUnsignedInt (0); 
  109. feedArrayRow.writeShort ( directoryName.length ); 
  110. feedArrayRow.writeShort ( 0 ); 
  111. feedArrayRow.writeUTFBytes ( directoryName ); 
  112.   
  113. feedArrayRow.writeUnsignedInt ( 0 ); 
  114. feedArrayRow.writeUnsignedInt ( 0 ); 
  115. feedArrayRow.writeUnsignedInt ( 0 ); 
  116.   
  117. compressedData.writeBytes ( feedArrayRow ); 
  118.   
  119. var newOffset:int = this.compressedData.length; 
  120.   
  121. // Directory header 
  122. var addCentralRecord:ByteArray = new ByteArray; 
  123. addCentralRecord.endian = Endian.LITTLE_ENDIAN; 
  124. addCentralRecord.writeUnsignedInt ( 0x02014b50 ); 
  125. addCentralRecord.writeShort ( 0x0000 ); 
  126. addCentralRecord.writeShort ( 0x000a ); 
  127. addCentralRecord.writeShort ( 0x0000 ); 
  128. addCentralRecord.writeShort ( 0x0000 ); 
  129. addCentralRecord.writeUnsignedInt ( 0x00000000 ); 
  130. addCentralRecord.writeUnsignedInt ( 0 ); 
  131. addCentralRecord.writeUnsignedInt ( 0 ); 
  132. addCentralRecord.writeUnsignedInt ( 0 ); 
  133. addCentralRecord.writeShort ( directoryName.length ); 
  134. addCentralRecord.writeShort ( 0 ); 
  135. addCentralRecord.writeShort ( 0 ); 
  136. addCentralRecord.writeShort ( 0 ); 
  137. addCentralRecord.writeShort ( 0 ); 
  138. addCentralRecord.writeUnsignedInt ( 16 ); 
  139. addCentralRecord.writeUnsignedInt ( this.oldOffset ); 
  140.   
  141. this.oldOffset = newOffset; 
  142.   
  143. addCentralRecord.writeUTFBytes (directoryName); 
  144.   
  145. this.nbDirectory.push ( addCentralRecord ); 
  146. this.centralDirectory.writeBytes ( addCentralRecord ); 
  147.   
  148. /** 
  149. * Lets you add a file into a specific directory 
  150. * @param pBytes File stream 
  151. * @param pDirectory Directory name 
  152. * @example 
  153. * This example shows how to add files into directories : 
  154. * <div> 
  155. * <pre> 
  156. * myZip.addFile ( p_w_picpathByteArray, "p_w_picpaths/p_w_picpath.jpg" ); 
  157. * myZip.addFile ( p_w_picpathByteArray, "p_w_picpaths/funk/p_w_picpath.jpg" ); 
  158. * </pre> 
  159. * </div> 
  160. */ 
  161. public function addFile ( pBytes:ByteArray, pDirectory:String ):void 
  162. pDirectory = pDirectory.split ('\\').join ('/'); 
  163. var pDirectory_byte:* = new ByteArray(); 
  164. pDirectory_byte.writeMultiByte(pDirectory, "GBK"); 
  165.   
  166. var feedArrayRow:ByteArray = new ByteArray; 
  167. feedArrayRow.endian = Endian.LITTLE_ENDIAN; 
  168.   
  169. // Local File Header 
  170. feedArrayRow.writeUnsignedInt ( 0x04034b50 ); 
  171. feedArrayRow.writeShort ( 0x0014 ); 
  172. feedArrayRow.writeShort ( 0x0000 ); 
  173.   
  174. // File is deflated 
  175. feedArrayRow.writeShort ( this.compressionMethod == CompressionMethod.GZIP ? 0x0008 : 0x0000 ); 
  176.   
  177. feedArrayRow.writeUnsignedInt ( unixToDos ( new Date().getTime() ) ); 
  178.   
  179. var uncompressedLength:Number = pBytes.length; 
  180.   
  181. // CRC32 checksum 
  182. var crc:CRC32 = new CRC32; 
  183. crc.generateCRC32 ( pBytes ); 
  184. var compression:int = crc.getCRC32(); 
  185.   
  186. // If GZIP compression 
  187. if ( compressionMethod == CompressionMethod.GZIP ) 
  188. pBytes.compress(); 
  189. var copy:ByteArray = new ByteArray; 
  190. copy.writeBytes ( pBytes, 0, pBytes.length - 4 ); 
  191. var finalCopy:ByteArray = new ByteArray; 
  192. finalCopy.writeBytes ( copy, 2 ); 
  193. pBytes = finalCopy; 
  194.   
  195. var compressedLength:int = pBytes.length; 
  196.   
  197. feedArrayRow.writeUnsignedInt ( compression ); 
  198. feedArrayRow.writeUnsignedInt ( compressedLength ); 
  199. feedArrayRow.writeUnsignedInt ( uncompressedLength ); 
  200. feedArrayRow.writeShort ( pDirectory_byte.length ); 
  201. feedArrayRow.writeShort ( 0 ); 
  202. feedArrayRow.writeBytes ( pDirectory_byte ); 
  203. feedArrayRow.writeBytes ( pBytes ); 
  204.   
  205. // Data Descriptor 
  206. feedArrayRow.writeUnsignedInt ( compression ); 
  207. feedArrayRow.writeUnsignedInt ( compressedLength ); 
  208. feedArrayRow.writeUnsignedInt ( uncompressedLength ); 
  209.   
  210. compressedData.writeBytes ( feedArrayRow ); 
  211.   
  212. var newOffset:int = compressedData.length; 
  213.   
  214. // File header 
  215. var addCentralRecord:ByteArray = new ByteArray; 
  216. addCentralRecord.endian = Endian.LITTLE_ENDIAN; 
  217. addCentralRecord.writeUnsignedInt ( 0x02014b50 ); 
  218. addCentralRecord.writeShort ( 0x0000 ); 
  219. addCentralRecord.writeShort ( 0x0014 ); 
  220. addCentralRecord.writeShort ( 0x0000 ); 
  221. addCentralRecord.writeShort ( this.compressionMethod == CompressionMethod.GZIP ? 0x0008 : 0x0000 ); 
  222. addCentralRecord.writeUnsignedInt ( unixToDos ( new Date().getTime() ) ); 
  223. addCentralRecord.writeUnsignedInt ( compression ); 
  224. addCentralRecord.writeUnsignedInt ( compressedLength ); 
  225. addCentralRecord.writeUnsignedInt ( uncompressedLength ); 
  226. addCentralRecord.writeShort(pDirectory_byte.length); 
  227. addCentralRecord.writeShort ( 0 ); 
  228. addCentralRecord.writeShort ( 0 ); 
  229. addCentralRecord.writeShort ( 0 ); 
  230. addCentralRecord.writeShort ( 0 ); 
  231. addCentralRecord.writeUnsignedInt( 32 ); 
  232.   
  233. addCentralRecord.writeUnsignedInt ( this.oldOffset ); 
  234. this.oldOffset = newOffset; 
  235.   
  236. addCentralRecord.writeBytes ( pDirectory_byte ); 
  237.   
  238. this.nbDirectory.push ( addCentralRecord ); 
  239. this.centralDirectory.writeBytes ( addCentralRecord ); 
  240.   
  241. /** 
  242. * Lets you add a comment into the Zip file 
  243. * @param pComment The comment string to add 
  244. * @example 
  245. * This example shows how to add a comment for the current zip : 
  246. * <div><pre>myZip.addComment ( "Hello there !");</pre></div> 
  247. */ 
  248. public function addComment ( pComment:String ):void 
  249. comment = pComment; 
  250.   
  251. /** 
  252. * Lets you finalize and save the ZIP file and make it available for download 
  253. * @param pMethod Can be se to Method.LOCAL, the saveZIP will return the ZIP ByteArray. When Method.REMOTE is passed, just specify the path to the create.php file 
  254. * @param pURL The url of the create.php file 
  255. * @param pDownload Lets you specify the way the ZIP is going to be available. Use Download.INLINE if you want the ZIP to be directly opened, use Download.ATTACHMENT if you want to make it available with a save-as dialog box 
  256. * @param pName The name of the ZIP, only available when Method.REMOTE is used 
  257. * @return The ByteArray ZIP when Method.LOCAL is used, otherwise the method returns null 
  258. * @example 
  259. * This example shows how to save the ZIP with a download dialog-box : 
  260. * <div> 
  261. * <pre> 
  262. * myZIP.saveZIP ( Method.REMOTE, 'create.php', Download.ATTACHMENT, 'archive.zip' ); 
  263. * </pre> 
  264. * </div> 
  265. */ 
  266. public function saveZIP ( pMethod:String, pURL:String='', pDownload:String='inline', pName:String='archive.zip' ):* 
  267. output = new ByteArray; 
  268. output.endian = Endian.LITTLE_ENDIAN; 
  269. output.writeBytes ( this.compressedData ); 
  270. output.writeBytes ( this.centralDirectory ); 
  271. output.writeUnsignedInt ( 0x06054b50 ); 
  272. output.writeUnsignedInt ( 0x00000000 ); 
  273. output.writeShort ( this.nbDirectory.length ); 
  274. output.writeShort ( this.nbDirectory.length ); 
  275. output.writeUnsignedInt ( this.centralDirectory.length ); 
  276. output.writeUnsignedInt ( this.compressedData.length ); 
  277. var _loc_3:* = new ByteArray(); 
  278. _loc_3.writeMultiByte(comment, "GBK"); 
  279. output.writeShort(_loc_3.length); 
  280. output.writeBytes(_loc_3); 
  281.   
  282. if ( pMethod == Method.LOCAL ) return output
  283.   
  284. var header:URLRequestHeader = new URLRequestHeader ("Content-type""application/octet-stream"); 
  285. var myRequest:URLRequest = new URLRequest ( pURL+'?name='+pName+'&amp;method='+pDownload ); 
  286. myRequest.requestHeaders.push (header); 
  287. myRequest.method = URLRequestMethod.POST; 
  288. myRequest.data = saveZIP ( Method.LOCAL ); 
  289.   
  290. navigateToURL ( myRequest, "_blank" ); 
  291.   
  292. return null
  293.   
  294. private function unixToDos( pTimeStamp:Number ):Number 
  295. var currentDate:Date  = new Date ( pTimeStamp ); 
  296.   
  297. if ( currentDate.getFullYear() < 1980 ) currentDate = new Date (1980, 1, 1, 0, 0, 0); 
  298.   
  299. return ( (currentDate.getFullYear() - 1980) << 25) | (currentDate.getMonth() << 21) | (currentDate.getDate() << 16) | 
  300. (currentDate.getHours() << 11) | (currentDate.getMinutes() << 5) | (currentDate.getSeconds() >> 1); 
  301.   
  302.   
  303.   

使用方法是复制以上代码,保存为,然后下载http:///p/aszip/downloads/list 解压ASZip 0.2版本后,把保存的直接覆盖到org/aszip/zip 目录下,即可使用。