apache-flex 在客户端上传之前压缩文件

woobm2wo  于 2022-11-01  发布在  Apache
关注(0)|答案(6)|浏览(169)

基本上,我将处理大型XML文件(大约20 - 50 MB)。这些文件需要上传到服务器上。
我知道用javascript处理文件是不可能的,也不可能在客户端实现HTTP压缩。
我的问题是,是否存在任何解决方案(flash /动作脚本),压缩一个文件,并有一个javascript API?
场景是这样的:
1.正在尝试上载50 MB XML文件
1.在上传之前,用Javascript抓取它并将其发送到压缩器。
1.上载压缩文件,而不是原始文件。

gdrx4gfi

gdrx4gfi1#

你可以使用JSZip。对于输入,它支持String/ArrayBuffer/Uint8Array/Buffer,但 * 不 * blob s,这是你从一个<input type="file"/>中用javascript得到的:
File对象是Blob的一种特定类型,可以在Blob可以
(link)
因此,您必须首先将blob/文件转换为ArrayBuffer,例如使用FileReader.readAsArrayBuffer()。注意,此函数异步工作,需要使用回调函数。也有FileReaderSync可用,但“此接口仅在worker中可用,因为它启用了可能会阻塞的同步I/O”,因此我看不出使用它有什么好处。
EDIT。我不确定,但我相信您现在可以跳过blob-〉ArrayBuffer转换,直接压缩File对象。
如果php的指令max_file_uploads被您的web空间主机设置为一个较小的数字,那么整个方法就特别有用,因为现在您唯一需要担心的是upload_max_filesize
以下代码示例摘录(使用JQuery)用于在提交前将一个multiple文件输入的多个文件放入zip中,以供参考:

  1. // onclick:
  2. var fileInput = $(':file');
  3. var files = [];
  4. $.each(fileInput[0].files, function(i, file) {
  5. files.push(file);
  6. });
  7. var zip = new JSZip();
  8. function addFileToZip(n) {
  9. if(n >= files.length) {
  10. zippingComplete(zip.generate({type:"blob", compression:"deflate"}));
  11. return;
  12. }
  13. var file = files[n];
  14. var arrayBuffer;
  15. var fileReader = new FileReader();
  16. fileReader.onload = function() {
  17. arrayBuffer = this.result;
  18. zip.file(file.name, arrayBuffer);
  19. addFileToZip(n + 1);
  20. };
  21. fileReader.readAsArrayBuffer(file);
  22. }
  23. addFileToZip(0);
  24. function zippingComplete(zip) {
  25. formData = new FormData();
  26. formData.append('fileZip', zip);
  27. formData.append("param1", "blah");
  28. $.ajax({
  29. data: formData,
  30. //... etc

在服务器端,您将访问$_FILES["fileZip"]

展开查看全部
brqmpdu1

brqmpdu12#

Flash的ByteArray内置实现有一个方法(ByteArray::deflate,用于缩小(字节数组的)内容。缩小算法是DEFLATE Compressed Data Format Specification version 1.3
还有一个ByteArray::compress方法,它使用zlib算法进行压缩
稍等一下,我将为您编写一些示例代码,以使用此类并将其公开给JavaScript。

编辑

我已经在http://www.filefactory.com/file/cf8a39c/n/demo5.zip上传了文件

编辑2对于无法下载文件的用户:

我在demo5.fla中的ActionScript代码(编译为demo5.swf)

  1. import flash.external.ExternalInterface;
  2. import flash.net.FileReference;
  3. import flash.events.Event;
  4. import flash.utils.ByteArray;
  5. if(ExternalInterface.available) {
  6. //flash.system.Security.allowDomain("localhost");
  7. ExternalInterface.addCallback("deflate", doDeflate);
  8. ExternalInterface.addCallback("compress", doCompress);
  9. }
  10. var method:String="deflate";
  11. var b:ByteArray;
  12. function doCompress(_data:String):void {
  13. method="compress";
  14. exec(_data);
  15. }
  16. function doDeflate(_data:String):void {
  17. method="deflate";
  18. exec(_data);
  19. }
  20. function exec(_data:String):void {
  21. b=new ByteArray();
  22. b.writeUTFBytes(_data);
  23. b.position=0;
  24. if(method=="compress") {
  25. b.compress();
  26. } else if(method=="deflate") {
  27. b.deflate();
  28. }
  29. executed();
  30. }
  31. function executed():void {
  32. if(ExternalInterface.available) {
  33. b.position=0;
  34. var str:String=b.readUTFBytes(b.bytesAvailable);
  35. ExternalInterface.call("onExec", str);
  36. }
  37. }

我的HTML代码嵌入swf:

  1. <button onclick="doDeflate()">Deflate</button>
  2. <button onclick="doCompress()">Compress</button>
  3. <div id="flashContent">
  4. <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="demo5" align="middle">
  5. <param name="movie" value="demo5.swf" />
  6. <param name="quality" value="high" />
  7. <param name="bgcolor" value="#ffffff" />
  8. <param name="play" value="true" />
  9. <param name="loop" value="true" />
  10. <param name="wmode" value="window" />
  11. <param name="scale" value="showall" />
  12. <param name="menu" value="true" />
  13. <param name="devicefont" value="false" />
  14. <param name="salign" value="" />
  15. <param name="allowScriptAccess" value="always" />
  16. <embed src="demo5.swf" quality="high" bgcolor="#869ca7"
  17. width="1" height="1" name="demo5" align="middle"
  18. play="true" loop="false" quality="high" allowScriptAccess="always"
  19. type="application/x-shockwave-flash"
  20. pluginspage="http://www.macromedia.com/go/getflashplayer">
  21. </embed>
  22. </object>
  23. </div>

最后是JavaScript代码:

  1. function doDeflate() {
  2. var data="fdg fhnkl,hgltrebdkjlgyu ia43uwriu67ri8m nirugklhvjsd fgvu";
  3. //DATA CONTAINS DATA TO BE DEFLATED
  4. thisMovie("demo5").deflate(data);
  5. }
  6. function doCompress() {
  7. var data="fdg fhnkl,hgltrebdkjlgyu ia43uwriu67ri8m nirugklhvjsd fgvu";
  8. //DATA CONTAINS DATA TO BE DEFLATED
  9. thisMovie("demo5").compress(data);
  10. }
  11. function onExec(data) {
  12. //DATA CONTAINS THE DEFLATED DATA
  13. alert(data);
  14. }
  15. function thisMovie(movieName) {
  16. if (navigator.appName.indexOf("Microsoft") != -1) {
  17. return window[movieName];
  18. } else {
  19. return document[movieName];
  20. }
  21. }
展开查看全部
xuo3flqw

xuo3flqw3#

如果由于某种原因,您无法找到一个在JavaScript中适用于所有主流浏览器的解决方案,我知道这里有一个AS 3压缩库:http://code.google.com/p/ascompress/
还有一个不太酷的选择,如果你的目标用户有点技术,为什么不让他们上传一个xml的.zip文件呢?然后在服务器端,你可以根据需要解压缩和处理。
无论哪种方式,在服务器端,你会想解压缩/解压,这应该很容易谷歌的解决方案,如果你还没有一个在脑海中。

gywdnpxw

gywdnpxw4#

使用Silverlight,您可以在客户端压缩文件,这种方法适用于所有主流浏览器。此外,您还可以通过JavaScript与Silverlight部件进行交互。此外,如果用户需要上传多个文件,Silverlight部件可以显示一个单个对话框,用于选择所有文件。唯一的缺点是您的客户端必须安装Silverlight插件。

slhcrj9b

slhcrj9b5#

考虑查看另一个stackoverflow post。阅读这两个答案可以很好地描绘压缩现实。
我正在考虑实现一个Silverlight的Flex解决方案,压缩客户端,如果用户不想安装它,压缩和解压缩文件服务器端。将更新此职位时,找到一个解决方案。
安装该控件可以节省用户的时间,这通常是正确的。对于服务器来说,它可以节省带宽和压缩处理。

b91juud3

b91juud36#

有一些javascript库的霍夫曼压缩免费可用,例如https://github.com/wilkerlucio/huffman_js,但我认为你的任务是不可能的,因为与javascript和html它是不可能加载大量的数据到浏览器或客户端的内存。

相关问题