ASZip0.2版本解決中文文件名亂碼問題

ASZip文件庫是開源的AS3版–Zip壓縮算法,具體示例應用可見http://code.google.com/p/aszip/。目前的最新版本是0.2版。最近在項目中須要用到該第三方類庫來支持Flash對圖片文件的批量打包上傳。因爲是外國友人寫的,因此對中文命名的圖片文件進行壓縮時,就會報錯,只能支持用非中文的命名的圖片文件。 php

下面是我在做者原有代碼的基礎上作了些改進,使其能良好的支持中英文命名的文件,進而對文件打包壓縮。

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

使用方法是複製以上代碼,保存爲ASZip.as,而後下載http://code.google.com/p/aszip/downloads/list 解壓ASZip 0.2版本後,把保存的ASZip.as直接覆蓋到org/aszip/zip 目錄下,便可使用。 算法

相關文章
相關標籤/搜索