在客户端上载之前进行文件压缩

fek*_*egy 11 javascript apache-flex compression flash upload

基本上我将使用大型XML文件(大约20 - 50 MB).这些文件需要上传到服务器上.

我知道用javascript触摸文件是不可能的,也不能在客户端实现HTTP压缩.

我的问题是,如果存在压缩文件并具有javascript API的任何解决方案(闪存/动作脚本)?

场景是这样的:

  1. 尝试上传50 MB的XML文件
  2. 在上传之前,使用Javascript抓取它并将其发送到压缩器.
  3. 上传压缩文件而不是原始文件.

Pra*_*adi 5

Flash的内置实施ByteArray中的有一个方法(ByteArray::deflate放气ByteArray的内容()deflate算法是DEFLATE压缩数据格式规范1.3版.

还有一种ByteArray::compress使用zlib算法压缩的方法

稍等一下,我将为您编写一些示例代码以使用此类并将其公开给JavaScript.

编辑

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

编辑2对于那些无法下载文件的人:

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

import flash.external.ExternalInterface;
import flash.net.FileReference;
import flash.events.Event;
import flash.utils.ByteArray;

if(ExternalInterface.available) {
    //flash.system.Security.allowDomain("localhost");
    ExternalInterface.addCallback("deflate", doDeflate);
    ExternalInterface.addCallback("compress", doCompress);
}

var method:String="deflate";
var b:ByteArray;
function doCompress(_data:String):void {
    method="compress";
    exec(_data);
}

function doDeflate(_data:String):void {
    method="deflate";
    exec(_data);
}

function exec(_data:String):void {
    b=new ByteArray();
    b.writeUTFBytes(_data);
    b.position=0;
    if(method=="compress") {
        b.compress();
    } else if(method=="deflate") {
        b.deflate();
    }
    executed();
}

function executed():void {
    if(ExternalInterface.available) {
        b.position=0;
        var str:String=b.readUTFBytes(b.bytesAvailable);
        ExternalInterface.call("onExec", str);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的HTML代码嵌入swf:

<button onclick="doDeflate()">Deflate</button>
<button onclick="doCompress()">Compress</button>
<div id="flashContent">
    <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="demo5" align="middle">
        <param name="movie" value="demo5.swf" />
        <param name="quality" value="high" />
        <param name="bgcolor" value="#ffffff" />
        <param name="play" value="true" />
        <param name="loop" value="true" />
        <param name="wmode" value="window" />
        <param name="scale" value="showall" />
        <param name="menu" value="true" />
        <param name="devicefont" value="false" />
        <param name="salign" value="" />
        <param name="allowScriptAccess" value="always" />

        <embed src="demo5.swf" quality="high" bgcolor="#869ca7"
             width="1" height="1" name="demo5" align="middle"
             play="true" loop="false" quality="high" allowScriptAccess="always"
             type="application/x-shockwave-flash"
             pluginspage="http://www.macromedia.com/go/getflashplayer">
        </embed>
    </object>
</div>
Run Code Online (Sandbox Code Playgroud)

最后是javascript代码:

function doDeflate() {
    var data="fdg fhnkl,hgltrebdkjlgyu ia43uwriu67ri8m nirugklhvjsd fgvu";
    //DATA CONTAINS DATA TO BE DEFLATED
    thisMovie("demo5").deflate(data);
}

function doCompress() {
    var data="fdg fhnkl,hgltrebdkjlgyu ia43uwriu67ri8m nirugklhvjsd fgvu";
    //DATA CONTAINS DATA TO BE DEFLATED
    thisMovie("demo5").compress(data);
}

function onExec(data) {
    //DATA CONTAINS THE DEFLATED DATA
    alert(data);
}

function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName];
    } else {
        return document[movieName];
    }
}
Run Code Online (Sandbox Code Playgroud)


phi*_*294 5

你可以使用JSZip.对于输入,它支持String/ArrayBuffer/Uint8Array/Buffer,但不支持 blob s,这是你从<input type="file"/>javascript 获得的:

File对象是特定种类的Blob,可以在Blob可以使用的任何上下文中使用

(链接)

因此,您必须首先将blob /文件转换为例如ArrayBuffer,例如使用FileReader.readAsArrayBuffer().请注意,此函数异步工作,要求回调使用.还有一个FileReaderSync可用,但"此接口仅在工作人员中可用,因为它启用了可能阻止的同步I/O",因此我认为使用它没有任何好处.

(编辑.我​​不确定,但我相信你现在可以跳过blob-> ArrayBuffer转换,只需压缩File对象.)

如果max_file_uploads您的网站空间主机将php的指令设置为较小的数字,这整个方法特别有用,现在您唯一需要担心的是upload_max_filesize

作为参考,在提交之前,使用代码示例摘录(使用JQuery)将一个multiple文件输入的几个文件放入zip中:

// onclick:
var fileInput = $(':file');
var files = [];
$.each(fileInput[0].files, function(i, file) {
    files.push(file);
});

var zip = new JSZip();
function addFileToZip(n) {
    if(n >= files.length) {
        zippingComplete(zip.generate({type:"blob", compression:"deflate"}));
        return;
    }
    var file = files[n];                    
    var arrayBuffer;
    var fileReader = new FileReader();
    fileReader.onload = function() {
        arrayBuffer = this.result;
        zip.file(file.name, arrayBuffer);
        addFileToZip(n + 1);
    };
    fileReader.readAsArrayBuffer(file);
}
addFileToZip(0);

function zippingComplete(zip) {
    formData = new FormData();
    formData.append('fileZip', zip);
    formData.append("param1", "blah");
    $.ajax({
        data: formData,
        //... etc
Run Code Online (Sandbox Code Playgroud)

服务器方面,您将访问$_FILES["fileZip"].