基本上我将使用大型XML文件(大约20 - 50 MB)。这些文件需要上传到服务器上。
我知道用javascript触摸文件是不可能的,也不能在客户端实现HTTP压缩。
我的问题是,如果存在压缩文件并具有javascript API的任何解决方案(闪存/动作脚本)?
情景如下:
答案 0 :(得分:5)
Flash内置的ByteArray实现有一个方法(ByteArray::deflate
来缩小内容(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)
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);
}
}
我的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>
最后是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];
}
}
答案 1 :(得分:5)
您可以使用JSZip。对于输入,它支持String/ArrayBuffer/Uint8Array/Buffer,但不是 blob
,这是您使用javascript从<input type="file"/>
获得的内容:
File对象是特定种类的Blob,可以在Blob可以使用的任何上下文中使用
所以你必须将blob /文件转换为例如首先是ArrayBuffer,例如使用FileReader.readAsArrayBuffer()
。请注意,此函数异步工作,要求回调使用。还有一个FileReaderSync可用,但“此接口仅在工作人员中可用,因为它启用了可能阻止的同步I / O”,因此我认为使用它没有任何好处。
(编辑。我不确定,但我相信您现在可以跳过blob-&gt; ArrayBuffer转换,只需压缩File对象。)
如果您的网站空间主机将php的指令max_file_uploads
设置为较小的数字,这整个方法特别有用,现在您唯一需要担心的是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
服务器方面,您将访问$_FILES["fileZip"]
。
答案 2 :(得分:1)
如果出于某种原因无法获得适用于所有主流浏览器的JavaScript解决方案,我知道这里有一个AS3压缩库:http://code.google.com/p/ascompress/。
另外,一个不太酷的选项,如果你的目标用户有点技术讽刺,为什么不让他们上传xml的.zip文件?然后在服务器端,您可以根据需要解压缩和处理。
无论哪种方式在服务器端,你都需要解压缩/解压缩,如果你还没有想到解决方案,这应该很容易google解决方案。
答案 3 :(得分:1)
使用Silverlight,您可以在客户端压缩文件,这种方法适用于所有主流浏览器。此外,您可以通过JavaScript与Silverlight小部件进行交互。此外,如果用户需要上传多个文件,您的Silverlight小部件可以显示单个对话框以选择所有文件。唯一的缺点是您的客户必须安装Silverlight插件。
答案 4 :(得分:1)
考虑查看其他stackoverflow post。阅读这两个答案描绘了压缩现实的良好画面。
我正在考虑实施压缩客户端的Silverlight of Flex解决方案,如果用户不想安装它,请压缩和解压缩文件服务器端。将在找到解决方案后更新此帖子。
安装控件将作为节省时间出售给用户,这通常是正确的。对于服务器,它将是带宽和压缩处理保护程序。
答案 5 :(得分:0)
有一些huffman压缩的javascript库可以免费使用,例如https://github.com/wilkerlucio/huffman_js,但我认为你的任务是不可能的,因为使用javascript和html,无法将大量数据加载到浏览器或客户端的内存中。