+大きなファイルのJavaをアップロード

 偽造は前uploadifyファイルアップロードHTML5プラグインのバージョンを書いて、友人が見ていないこちらをクリックして、〜自宅で友人の多くは、私もプロジェクトに慣れる見ユーザアバターのアップロード、または各かアップロードメディアファイルの種類だけでなく、パーソナライズされたビジネスニーズの多様を満たすことができます。少し幸せ。

  しかし、再び、すべてのニーズを満たすことは困難であるどのように柔軟なプラグインに関係なくは、例えば、あなたは2Gにファイルをアップロードします。今、私たちのネットワーク速度に、私はすぐに半時間を渡すために持っていることを恐れています。問題は、時間の90%にアップロードする場合は、誤って、ブラウザや手フリック押しますF5を閉じて終了し、すべてがもう一度起動する必要はありません、です。このユーザーの経験があまりにも悪いです。だから、それは非常に必要再開。私は説明しません。履歴書、非常に多くの年のためのQQのパスとファイルが何であるか、我々はそれを見てきました。

  ここではHTTPを持っている技術的なポイントがあります。提出またはHTML5いるFormDataの伝統的な形式の使用は「一括」ファイルのファイル・サーバに、提出すると、その後転送を取得、他の操作の名前を変更して、そのため、リアルタイムの一部にアップロードされたファイルを保存することはできませんです。HTTPプロトコルでは、我々は、ブラウザとサーバが提出するファイルストリームの形にすることはできません長い接続を維持することはできません。そこで問題は、特に以下の点に対処します:

  1. ファイルをアップロードするには、小片をアップロードするための時間を分割します。サービスオリジナルパーツに追加書類の受領後に終了し、最終的に完全なファイルにマージします。

  2. ファイルをアップロードするために、各ピースは、この場所をカットしなければならないかを決定するために、ファイルのサイズをアップロードし得る前に

  3. 各アップロードされた後、完全な更新レコードは、ファイルのサイズをアップロードされました

  4. コンテンツは、ファイル、ファイルBに追加されていないことを確認するために、クライアントとサーバーのファイルを特定します

  Zhangxin徐兄弟への参照では、この記事で、技術は私が私のプラグインHuploadify、HTTP機能の追加が成功に学ぶことができます。他人への技術やプラグインで。

事業/技術的なポイント

  最初のものは最初、我々は10Mファイルがある場合は、各切断は1Mをアップロードし、明確にするために、我々が完了するまでに10件のリクエストを送信する必要があります。httpプロトコルでは、あなただけ行うことができます。3つの手順を完了するためのブレークポイントのアップロード:

  1. ファイルを選択した後、サーバー上のファイルサイズ、カスタム関数またはローカルストレージにより取得することを取得。

  2. n番目のファイルサーバのチップを維持するために送信されたアップロードされたファイルのサイズを、切断に提出要求に応じて、サーバは、ファイルの内容を追加し続けます

  3. アップロードされた場合は、ファイルサイズが最後のアップロード、ファイルの合計サイズに達しました  

  まず、ファイルを分割し、HTML5は、BLOBデータ・タイプを追加し、データの方法を分割することができる提供する:スライス()、及びその使用列を、配列スライスバイナリファイルの一部をインターセプトすることができる()メソッドとして。

  その後、ファイルには、追加ますfile_put_contentsたびに、特定の文言が後を参照するか、良いパッケージ化、私のファイルをダウンロードすることができ、PHPで書かれた私の背景の追加部分を使用してファイルを保存した後、最初のfile_get_contentsとバイナリ形式のファイルを取得します。

  次に我々はまた、次のカットをアップロードする前に補正するためには、アップロードされたファイルのサイズを保存するために、リアルタイムを必要としています。HTML5のlocalStorageを使用すると、次の読み取りがローカル開始アップロードする前に、ローカルに保存されているのサイズにアップロードされた方法です。このアプローチは非常に限られているが、利用者は50%でアップロードされたファイル内のユーザーのページならば、話し、その後、ページB内の別の場所にファイルをアップロードしようとしていないローカルデータスチュワードの様々なを通じてクリア取っておくことローカルファイルからの結果は、アップロード、明らかに間違いを開始する場所から直接50%、および51%の読み取りをアップロードしました。問題は、ローカルでのみファイルAPI、サーバー上の正しいファイルではない右の試合を通じて、ファイルの元の名前を取得するには、あまりにも多くの情報を格納していません。だから、プロジェクトと実物では、データを格納するためにサーバに依存しなければなりませんでした。

  サーバー側のデータが存在することになるかについて、フロントエンドのデータを取るために、私は以下の話をする方法となっています。

  非常に多くの上の技術的なポイントは、実際には、多くの技術的な内容ハ〜私のプラグインは、それを使用する方法を見ることはありません。

レジューム機能を使用します

  ファイルの導入は、1はプラグインに導入を参照することができますについて話されていません。重要な点は、いくつかの構成では、最初の外観を追加することです。


breakPoints:false,//是否开启断点续传 fileSplitSize:1024*1024,//断点续传的文件块大小,单位Byte,默认1M getUploadedSize:null,//类型:function,自定义获取已上传文件的大小函数,用于开启断点续传模式,可传入一个参数file,即当前上传的文件对象,需返回number类型 saveUploadedSize:null,//类型:function,自定义保存已上传文件的大小函数,用于开启断点续传模式,可传入两个参数:file:当前上传的文件对象,value:已上传文件的大小,单位Byte saveInfoLocal:false,//用于开启断点续传模式,是否使用localStorage存储已上传文件大小

  这是插件中的默认配置值。一个续传功能竟然要配置五个项,真要命!不要着急听我慢慢道来,这五个并不是要同时出现的,是为了满足可能出现的复杂业务而准备的。

  breakPoints是开启断点续传的开关,要使用的话设为true,默认是不开启的。

  fileSplitSize是每次切割的文件片的大小,默认是1M,可根据实际情况来定。如果你的系统上传的文件普遍都在1G以上,可以配置的大一点。

  getUploadedSize是用来自定义获取已上传的文件大小的函数,还记得上面说过的localStorage的局限吧,所以我这里直接把获取文件大小的函数交给你来定义,你可以从session、cookie,从文件、数据库或者任何地方取,可以发送一个ajax请求到你想要的地址,传递你需要的参数。注意你定义的函数将来会被插件调用,所以一定要返回一个Number类型的结果。

  saveUploadedSize与getUploadedSize对应,你自己定义如何保存已上传文件的大小,只要你存的数据你自己能取到就OK。当然前提是你要注意到上面说过的localStorage的局限,确保你的逻辑正确能够操作到正确的文件。

  saveInfoLocal是当你使用localStorage保存数据时需要开启的一个开关。插件默认提供使用localStorage方式的支持。只要开启此选项就可以了。当然,这种情况下你的业务逻辑必须足够简单,比如只是做一个上传的demo,或者这系统的用户只有你一个人,你明白如何避开那些局限的地方。

  掌握了这五个配置的作用,你就可以实现一个足够灵活的断点上传功能了!在我打包好的文件里,提供了使用localStorage方式的demo,抱歉我无法将数据库表都发给你,所以只能用本地存储来演示。

在服务端保存数据

  用户在使用上传的时候可能有各种你意想不到的操作,这里我发挥想象描述一下用户可能的行为:

  • 同一台机器使用不同帐号登录,上传同一个文件

  • 文件上传了一部分,然后修改了文件内容,再次上传

  • 文件上传完成100%,再次上传该文件

  • 同一个页面有多个上传按钮,上传同一个文件,或在不同页面上传同一个文件

  仅仅上面四条,是不是情况就够复杂了?再加上你系统还有自己的业务逻辑,所以在服务端保存已上传文件数据是非常有必要的。而且保存数据和获取数据的函数都交给你来定义,抱着插件有足够的灵活性。

  因为涉及到了服务端的技术,无法演示,我将我项目中的真实使用场景在此讲解一下,来展示一下如何自已定义方法来实现服务端保存数据的可靠上传。我定义的getUploadedSize函数如下:

getUploadedSize:function(file){
            var data = {
                data : {
                    fileName : file.name,
                    lastModifiedDate : file.lastModifiedDate.getTime()
                }
            };
            var url = 'http://localhost/uploadfile/';
            var uploadedSize = 0;
            $.ajax({
                url : url,
                data : data,
                async : false,
                type : 'POST',
                success : function(returnData){
                    returnData = JSON.parse(returnData);
                    uploadedSize = returnData.uploadedSize;
                }
            });
            return uploadedSize;
        }

 

  我向后台的某个地址发送一个请求,传递文件名和文件的最后修改时间为参数,后台根据这两个参数来找到与前台所选择的文件对应的服务器上的文件,将服务器返回的文件大小return出去,来被插件使用。为什么要传递这两个参数呢?我们在前台无法知道服务器上的这个文件的名称,所以使用原始文件名作为一个辅助标识。为了防止用户在两次上传间隔修改了文件,我们把文件的最后修改时间也传给服务端,让服务端进行比较,若时间不对应则返回已上传大小为0,重新上传此文件。

  再来看后台都要做哪些工作。数据库中需要有一张表来记录每个已文件的情况,包含的字段大致有:

字段 描述
client_filename 文件在客户端的原始名称
server_filename 文件在服务器上重命名后的名称
last_modified_date 文件的最后修改时间,时间戳
status 文件的状态,已完成、未完成
uploaded_size 已上传文件的大小

  根据client_filename和last_modified_date,再加上系统中的其他关联信息,可以定位到本次上传的文件在服务端的大小,然后返回给客户端。当然这是我自己的用法,你也可以根据自己的需求灵活设计。总之最终的目的就是要找到前台选择的文件在服务器上真正对应的文件,并将已上传大小正确返回。

  另外需注意的一点,就是在续传的第二步,不断提交文件片的过程中,也需要服务端准确定位到相应的文件,不能把A的数据追加到B上。采用的方式也是提交fileName和lastModifyDate两个参数(已写在插件内部,可服务端直接获取),服务端找到对应的文件进行追加。

  另外再啰嗦一句,后台获取文件的时候需要取成二进制的,而我们提交是使用FormData来提交的,所以PHP代码需要这么写:

file_put_contents('uploads/'.$filename,file_get_contents($_FILES["file"]["tmp_name"]),FILE_APPEND);

  如果上面的说明还是不够清楚,就需要你自己来探索一下了,毕竟考虑到插件可能应用在复杂的系统中,很多工作还是需要你来做的。或者你也可以给我留言,我很乐意为你解答疑惑。

该版本的其他改动

  从1.0到2.0,Huploadify又新加了很多东西,不过只是新加,使用方式跟之前的没有变化。例如上面的断点续传功能,你如果不想使用,只需设置breakPoints为false即可,插件仍按照以前的方式工作。除了断点续传这个大头,插件还做了如下改动:

  1. 增加了onSelect回调函数,在选择了文件之后触发,用法与uploadify官网的一致

  2. 删除掉正在上传的文件,中断发送请求

  3. 完善了input file组件的accept属性支持,浏览时只显示运行的文件格式,就是这个东东:

  4. 对外开放了方法调用接口,upload、stop、cancel、disable、ennable。我在demo中有演示。使用方法如下:var up = $('#upload').Huploadify({

    auto:false,     fileTypeExts:'*.jpg;*.png;*.exe;*.mp3;*.mp4;*.zip;*.doc;*.docx;*.ppt;*.pptx;*.xls;*.xlsx;*.pdf',     multi:true });  up.upload(1);//开始上传文件,接收一个参数,表示上传第几个文件,可传入*上传队列中的所有文件 up.stop();//暂停上传队列中的所有文件,不接收参数。用于开启了断点需传 up.cancel(1);//删除队列中的某个文件,接收一个参数,表示删除第几个文件,可传入*删除队列中的所有文件 up.disable();//使选择文件按钮失效,不接收参数 up.ennable();//使选择文件按钮生效,不接收参数  5. 修改其他已知bug

结束

  插件刚刚完成,与我们的后端程序员调试完成了断点续传功能暂未发现问题,欢迎大家在使用的时候给我提任何问题。老实来讲这个功能使用起来还是挺费解的,为了最大程度的保证灵活做成这样,大家可以与我多多交流~

  我在demo中使用了本地存储来做已上传文件大小的保存,下载压缩包后可看一下效果。上传一个比较大的视频文件,上传到中间关闭浏览器,再次打开浏览器上传同一个文件,会看到从上次断掉的地方继续上传。
详细内容可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/

おすすめ

転載: www.cnblogs.com/songsu/p/11350471.html