我的工作将主要涉及处理大型XML文件(约20-50 MB)。这些文件需要上传到服务器。
我知道不能使用JavaScript操作文件,也无法在客户端实现HTTP压缩。
我的问题是:是否存在任何解决方案(例如Flash / ActionScript),可以对文件进行压缩并具有JavaScript API?
具体情况如下:
- 尝试上传50 MB的XML文件
- 在上传之前使用JavaScript获取文件并将其发送到压缩器。
- 上传压缩后的文件而不是原始文件。
我的工作将主要涉及处理大型XML文件(约20-50 MB)。这些文件需要上传到服务器。
我知道不能使用JavaScript操作文件,也无法在客户端实现HTTP压缩。
我的问题是:是否存在任何解决方案(例如Flash / ActionScript),可以对文件进行压缩并具有JavaScript API?
具体情况如下:
blob
,这是您从<input type="file"/>
中获取的内容:
(链接) 所以您需要先将blob/file转换为ArrayBuffer,例如使用File对象是Blob的一种特定类型,可以在任何Blob可用的上下文中使用
FileReader.readAsArrayBuffer()
。请注意,此函数是异步工作的,需要使用回调。也有一个FileReaderSync可用,但“此接口仅在workers中可用,因为它启用了可能会阻塞的同步I/O”,因此我认为没有使用它的好处。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"]
。
compression: 'deflate'
已经让 JSZip 压缩了 zip 结果。你可以通过增加压缩选项到等级 9 来进一步提高压缩比率,参见:https://stuk.github.io/jszip/documentation/api_jszip/generate_async.html - phil294ByteArray::deflate
)来压缩字节数组的内容。压缩算法是DEFLATE Compressed Data Format Specification version 1.3。ByteArray::compress
方法,使用zlib算法进行压缩。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);
}
}
以下是嵌入swf的HTML代码:
<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>
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];
}
}
建议查看stackoverflow post。阅读两个回答可以很好地了解压缩现实情况。
我正在考虑实现一种Silverlight或Flex解决方案,该方案在客户端进行压缩,如果用户不想安装它,则在服务器端对文件进行压缩和解压缩。找到解决方案后会更新此帖子。
安装控件将被推销给用户作为节省时间的方法,这通常是正确的。对于服务器来说,这将是节省带宽和压缩处理的好方法。
如果由于某种原因,您无法在所有主要浏览器中使用JavaScript解决方案,我知道这里有一个AS3压缩库:http://code.google.com/p/ascompress/。
此外,如果您的目标用户在技术上有一定的了解,为什么不让他们上传一个xml的.zip文件呢?然后在服务器端,您可以根据需要进行解压缩和处理。
无论哪种方式,在服务器端,您都需要进行解压缩/解压缩,如果您还没有想到解决方案,那么应该很容易通过谷歌搜索找到解决方案。
有一些免费提供的哈夫曼压缩的JavaScript库,例如https://github.com/wilkerlucio/huffman_js,但我认为你的任务是不可能完成的,因为使用JavaScript和HTML无法将大量数据加载到浏览器或客户端内存中。