基本上,我將使用大型XML文件(大約20-50 MB)。這些文件需要上傳到服務器上。在客戶端上傳之前進行文件壓縮
我知道用JavaScript觸摸文件是不可能的,也不可能在客戶端實現HTTP壓縮。
我的問題是,如果任何解決方案(閃存/動作腳本)壓縮文件,並有一個javascript API?
的情況是這樣的:
- 要上傳50 MB的XML文件
- 上傳之前抓住它的JavaScript,並將其發送到壓縮機。
- 上傳壓縮文件,而不是原始文件。
基本上,我將使用大型XML文件(大約20-50 MB)。這些文件需要上傳到服務器上。在客戶端上傳之前進行文件壓縮
我知道用JavaScript觸摸文件是不可能的,也不可能在客戶端實現HTTP壓縮。
我的問題是,如果任何解決方案(閃存/動作腳本)壓縮文件,並有一個javascript API?
的情況是這樣的:
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
EDIT 2文件對於那些誰也無法下載文件:
我ActionScript代碼在demo5.fla(編譯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];
}
}
謝謝,我正在等待它。 :)另外,使用Flash的文件處理很容易嗎?我猜爲了得到你需要使用Flash的文件對話框的文件,然後壓縮它,然後以某種方式將它發送到服務器... – feketegy
@feketegy,我已經在32分鐘前添加了上傳(不知道爲什麼之後我添加的評論沒有發佈)。無論如何,它中的html包含很明顯的javascript(帶有註釋),所以如果你什麼都沒有得到,不要問它。一個問題是:你將不得不通過http://域來運行html,或者向你的flash播放器添加一個例外(你的選擇) –
感謝你們,我還可以通過,閃光燈?在JavaScript中,我只能訪問文件的路徑,而沒有其他。所以一旦文件被壓縮,你有什麼建議如何將它發送到服務器? – feketegy
有一些JavaScript霍夫曼壓縮自由使用,例如https://github.com/wilkerlucio/huffman_js的庫,但我認爲,你的任務是不可能的,因爲用JavaScript和HTML這是不可能的巨大的數據加載到瀏覽器或客戶端的內存。
如果因爲某種原因你無法獲得適用於所有主流瀏覽器的JavaScript解決方案,我知道這裏有一個AS3壓縮庫:http://code.google.com/p/ascompress/。
此外,如果您的目標用戶有點技術含量較高,那麼爲什麼不讓他們上傳xml的.zip文件?然後在服務器端,您可以根據需要解壓縮並進行處理。
無論哪種方式在服務器端,你會想要解壓縮/解壓縮,如果你還沒有一個解決方案,這應該很容易谷歌的解決方案。 。
感謝您的鏈接。這個解決方案是否有Javascript API?我不熟悉Flash/Actionscript(我只是一個用戶)。另外,我不能讓用戶事先壓縮XML文件。不幸的是,這必須是一個自動化的過程,雖然這將是理想的... – feketegy
你可以在ActionScript中處理它,因爲它有它自己的文件瀏覽器。如果您需要它與JavaScript進行交談,但是您可以使用AS3的ExternalInterface。 Pranav的上面有一個很好的解決方案。 – ToddBFisher
使用Silverlight,你可以在客戶端壓縮文件,這種方法適用於所有主流瀏覽器。而且,您可以通過JavaScript與Silverlight小部件進行交互。此外,如果用戶需要上傳多個文件,則Silverlight小部件可以顯示一個單個對話框,用於選擇所有文件。唯一的缺點是你的客戶必須安裝Silverlight插件。
請考慮查看此其他stackoverflow post。閱讀這兩個答案描繪了壓縮現實的一張好照片。
我正在考慮實施壓縮客戶端的Silverlight of Flex解決方案,如果用戶不想安裝它,請壓縮和解壓縮文件服務器端。將在找到解決方案時更新此帖子。
安裝控制器將作爲節省時間的銷售給用戶,這通常是正確的。對於服務器來說,這將是一個帶寬和壓縮處理保護程序。
您可以使用JSZip。對於輸入,它支持String/ArrayBuffer/Uint8Array/Buffer,但不blob
s,這是你從一個<input type="file"/>
得到什麼使用javascript:
File對象是特定種類的Blob的,並且可以在任何上下文中使用一個斑點可以
所以你必須將BLOB /文件轉換成如首先是ArrayBuffer,例如使用FileReader.readAsArrayBuffer()
。請注意,此功能異步工作,要求回調使用。還有一個可用的FileReaderSync,但「此接口僅在工作中可用,因爲它啓用了可能會阻塞的同步I/O」,所以我沒有看到使用它的好處。
(編輯,我不知道,但我相信你現在可以跳過blob-> ArrayBuffer轉換和壓縮簡單File對象。)
這整個的做法是,如果PHP的指令max_file_uploads
是特別有用的通過你的網站主機設置爲一個小數目,對於現在的唯一的事情你必須要擔心的是upload_max_filesize
作爲參考,代碼示例摘錄的內容(使用JQuery
),用於把一個multiple
文件輸入的幾個文件提交前的郵編:
// 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"]
。
您可以跳過版本3+中的blob-> ArrayBuffer轉換。但對於較舊的版本(在我的情況下爲2.6),您的解決方案非常有用 –
我發現了這個,但我從來沒有使用它(並沒有Flash在這裏):http://jszip.stuartk.co.uk/ – AsTheWormTurns
感謝您的鏈接,但基本上我需要一個解決方案,適用於所有主要瀏覽器如IE7 +,FF,Safari和Chrome。 – feketegy