php web开发——文件的上传和下载 – 泽优软件博客 http://blog.ncmem.com/wordpress 荆门泽优软件有限公司官方博客 Tue, 03 Feb 2026 07:52:15 +0000 zh-Hans hourly 1 https://wordpress.org/?v=6.7.5 Java Web 项目的文件/文件夹上传下载 http://blog.ncmem.com/wordpress/2019/12/17/java-web-%e9%a1%b9%e7%9b%ae%e7%9a%84%e6%96%87%e4%bb%b6-%e6%96%87%e4%bb%b6%e5%a4%b9%e4%b8%8a%e4%bc%a0%e4%b8%8b%e8%bd%bd-2/ Tue, 17 Dec 2019 09:48:20 +0000 http://blog.ncmem.com/wordpress/?p=1631 继续阅读 Java Web 项目的文件/文件夹上传下载]]> 一、 功能性需求与非功能性需求

要求操作便利,一次选择多个文件和文件夹进行上传;
支持PC端全平台操作系统,Windows,Linux,Mac

支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。

支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同。

支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验;
支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。

支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留进度。

支持文件夹结构管理,支持新建文件夹,支持文件夹目录导航

交互友好,能够及时反馈上传的进度;

服务端的安全性,不因上传文件功能导致JVM内存溢出影响其他功能使用;

最大限度利用网络上行带宽,提高上传速度;


二、 设计分析

对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传

从上传的效率来看,利用多线程并发上传能够达到最大效率。


三、解决方案:

文件上传页面的前端可以选择使用一些比较好用的上传组件,例如百度的开源组件WebUploader,泽优软件的up6,这些组件基本能满足文件上传的一些日常所需功能,如异步上传文件,文件夹,拖拽式上传,黏贴上传,上传进度监控,文件缩略图,甚至是大文件断点续传,大文件秒传。 

在web项目中上传文件夹现在已经成为了一个主流的需求。在OA,或者企业ERP系统中都有类似的需求。上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便。能够提供更高级的应用支撑。

文件夹数据表结构

CREATE TABLE IF NOT EXISTS `up6_folders` (

  `f_id`               char(32) NOT NULL ,

  `f_nameLoc`               varchar(255) default ”,

  `f_pid`                   char(32) default ”,

  `f_uid`                   int(11) default ‘0’,

  `f_lenLoc`           bigint(19) default ‘0’,

  `f_sizeLoc`               varchar(50) default ‘0’,

  `f_pathLoc`               varchar(255) default ”,

  `f_pathSvr`               varchar(255) default ”,

  `f_pathRel`               varchar(255) default ”,

  `f_folders`               int(11) default ‘0’,

  `f_fileCount`        int(11) default ‘0’,

  `f_filesComplete`    int(11) default ‘0’,

  `f_complete`              tinyint(1) default ‘0’,

  `f_deleted`               tinyint(1) default ‘0’,

  `f_time`                  timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

  `f_pidRoot`               char(32) default ”,

  PRIMARY KEY  (`f_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

文件数据表结构

CREATE TABLE IF NOT EXISTS `up6_files` (

  `f_id`               char(32) NOT NULL,

  `f_pid`                   char(32) default ”,        /*父级文件夹ID*/

  `f_pidRoot`               char(32) default ”,        /*根级文件夹ID*/

  `f_fdTask`           tinyint(1) default ‘0’,     /*是否是一条文件夹信息*/

  `f_fdChild`               tinyint(1) default ‘0’,     /*是否是文件夹中的文件*/

  `f_uid`                   int(11) default ‘0’,

  `f_nameLoc`               varchar(255) default ”,    /*文件在本地的名称(原始文件名称)*/

  `f_nameSvr`               varchar(255) default ”,    /*文件在服务器的名称*/

  `f_pathLoc`               varchar(512) default ”,    /*文件在本地的路径*/

  `f_pathSvr`               varchar(512) default ”,    /*文件在远程服务器中的位置*/

  `f_pathRel`               varchar(512) default ”,

  `f_md5`                   varchar(40) default ”,     /*文件MD5*/

  `f_lenLoc`           bigint(19) default ‘0’,     /*文件大小*/

  `f_sizeLoc`               varchar(10) default ‘0’,    /*文件大小(格式化的)*/

  `f_pos`                   bigint(19) default ‘0’,     /*续传位置*/

  `f_lenSvr`           bigint(19) default ‘0’,     /*已上传大小*/

  `f_perSvr`           varchar(7) default ‘0%’,    /*已上传百分比*/

  `f_complete`              tinyint(1) default ‘0’,     /*是否已上传完毕*/

  `f_time`                  timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

  `f_deleted`               tinyint(1) default ‘0’,

  `f_scan`                  tinyint(1) default ‘0’,

  PRIMARY KEY  (`f_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

该项目核心就是文件分块上传。前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题。

* 如何分片;

* 如何合成一个文件;

* 中断了从哪个分片开始。

如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子。但是因为时间的关系还有工作的关系,我只能罢休了。最后我选择了百度的WebUploader来实现前端所需。

如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的。刚开始的时候,我是采用了前端生成了唯一uuid来做文件的标志,在每个分片请求上带上。不过后来在做秒传的时候我放弃了,采用了Md5来维护分块和文件关系。

在服务端合并文件,和记录分块的问题,在这方面其实行业已经给了很好的解决方案了。参考迅雷,你会发现,每次下载中的时候,都会有两个文件,一个文件主体,另外一个就是文件临时文件,临时文件存储着每个分块对应字节位的状态。

这些都是需要前后端密切联系才能做好,前端需要根据固定大小对文件进行分片,并且请求中要带上分片序号和大小。前端发送请求顺利到达后台后,服务器只需要按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件即可。

为了便于开发,我 将服务端的业务逻辑进行了如下划分,分成初始化,块处理,文件上传完毕等。

服务端的业务逻辑模块如下

 

 

功能分析:

文件夹生成模块

 

文件夹上传完毕后由服务端进行扫描代码如下

public class fd_scan

{

    DbHelper db;

    Connection con;

    PreparedStatement cmd_add_f = null;

    PreparedStatement cmd_add_fd = null;

    public FileInf root = null;//根节点

   

    public fd_scan()

    {

        this.db = new DbHelper();

        this.con = this.db.GetCon();       

    }

   

    public void makeCmdF()

    {

        StringBuilder sb = new StringBuilder();

        sb.append(“insert into up6_files (“);

        sb.append(” f_id”);//1

        sb.append(“,f_pid”);//2

        sb.append(“,f_pidRoot”);//3

        sb.append(“,f_fdTask”);//4

        sb.append(“,f_fdChild”);//5

        sb.append(“,f_uid”);//6

        sb.append(“,f_nameLoc”);//7

        sb.append(“,f_nameSvr”);//8

        sb.append(“,f_pathLoc”);//9

        sb.append(“,f_pathSvr”);//10

        sb.append(“,f_pathRel”);//11

        sb.append(“,f_md5”);//12

        sb.append(“,f_lenLoc”);//13

        sb.append(“,f_sizeLoc”);//14

        sb.append(“,f_lenSvr”);//15

        sb.append(“,f_perSvr”);//16

        sb.append(“,f_complete”);//17

       

        sb.append(“) values(“);

       

        sb.append(” ?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“)”);

 

        try {

            this.cmd_add_f = this.con.prepareStatement(sb.toString());

            this.cmd_add_f.setString(1, “”);//id

            this.cmd_add_f.setString(2, “”);//pid

            this.cmd_add_f.setString(3, “”);//pidRoot

            this.cmd_add_f.setBoolean(4, true);//fdTask

            this.cmd_add_f.setBoolean(5, false);//f_fdChild

            this.cmd_add_f.setInt(6, 0);//f_uid

            this.cmd_add_f.setString(7, “”);//f_nameLoc

            this.cmd_add_f.setString(8, “”);//f_nameSvr

            this.cmd_add_f.setString(9, “”);//f_pathLoc

            this.cmd_add_f.setString(10, “”);//f_pathSvr

            this.cmd_add_f.setString(11, “”);//f_pathRel

            this.cmd_add_f.setString(12, “”);//f_md5

            this.cmd_add_f.setLong(13, 0);//f_lenLoc

            this.cmd_add_f.setString(14, “”);//f_sizeLoc

            this.cmd_add_f.setLong(15, 0);//f_lenSvr            

            this.cmd_add_f.setString(16, “”);//f_perSvr

            this.cmd_add_f.setBoolean(17, true);//f_complete

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    public void makeCmdFD()

    {

        StringBuilder sb = new StringBuilder();

        sb.append(“insert into up6_folders (“);

        sb.append(” f_id”);//1

        sb.append(“,f_pid”);//2

        sb.append(“,f_pidRoot”);//3

        sb.append(“,f_nameLoc”);//4

        sb.append(“,f_uid”);//5

        sb.append(“,f_pathLoc”);//6

        sb.append(“,f_pathSvr”);//7

        sb.append(“,f_pathRel”);//8

        sb.append(“,f_complete”);//9

        sb.append(“) values(“);//

        sb.append(” ?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“)”);

 

        try {

            this.cmd_add_fd = this.con.prepareStatement(sb.toString());

            this.cmd_add_fd.setString(1, “”);//id

            this.cmd_add_fd.setString(2, “”);//pid

            this.cmd_add_fd.setString(3, “”);//pidRoot

            this.cmd_add_fd.setString(4, “”);//name

            this.cmd_add_fd.setInt(5, 0);//f_uid

            this.cmd_add_fd.setString(6, “”);//pathLoc

            this.cmd_add_fd.setString(7, “”);//pathSvr

            this.cmd_add_fd.setString(8, “”);//pathRel

            this.cmd_add_fd.setBoolean(9, true);//complete

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    protected void GetAllFiles(FileInf inf,String root)

    {

        File dir = new File(inf.pathSvr);

        File [] allFile = dir.listFiles();

        for(int i = 0; i < allFile.length; i++)

        {

            if(allFile[i].isDirectory())

            {

                FileInf fd = new FileInf();

                String uuid = UUID.randomUUID().toString();

                uuid = uuid.replace(“-“, “”);

                fd.id = uuid;

                fd.pid = inf.id;

                fd.pidRoot = this.root.id;

                fd.nameSvr = allFile[i].getName();

                fd.nameLoc = fd.nameSvr;

                fd.pathSvr = allFile[i].getPath();

                fd.pathSvr = fd.pathSvr.replace(“\\”, “/”);

                fd.pathRel = fd.pathSvr.substring(root.length() + 1);

                fd.perSvr = “100%”;

                fd.complete = true;

                this.save_folder(fd);

               

                this.GetAllFiles(fd, root);

            }

            else

            {

                FileInf fl = new FileInf();

                String uuid = UUID.randomUUID().toString();

                uuid = uuid.replace(“-“, “”);

                fl.id = uuid;

                fl.pid = inf.id;

                fl.pidRoot = this.root.id;

                fl.nameSvr = allFile[i].getName();

                fl.nameLoc = fl.nameSvr;

                fl.pathSvr = allFile[i].getPath();

                fl.pathSvr = fl.pathSvr.replace(“\\”, “/”);

                fl.pathRel = fl.pathSvr.substring(root.length() + 1);

                fl.lenSvr = allFile[i].length();

                fl.lenLoc = fl.lenSvr;

                fl.perSvr = “100%”;

                fl.complete = true;

                this.save_file(fl);

            }

        }

    }

   

    protected void save_file(FileInf f)

    {      

        try {

            this.cmd_add_f.setString(1, f.id);//id

            this.cmd_add_f.setString(2, f.pid);//pid

            this.cmd_add_f.setString(3, f.pidRoot);//pidRoot

            this.cmd_add_f.setBoolean(4, f.fdTask);//fdTask

            this.cmd_add_f.setBoolean(5, true);//f_fdChild

            this.cmd_add_f.setInt(6, f.uid);//f_uid

            this.cmd_add_f.setString(7, f.nameLoc);//f_nameLoc

            this.cmd_add_f.setString(8, f.nameSvr);//f_nameSvr

            this.cmd_add_f.setString(9, f.pathLoc);//f_pathLoc

            this.cmd_add_f.setString(10, f.pathSvr);//f_pathSvr

            this.cmd_add_f.setString(11, f.pathRel);//f_pathRel

            this.cmd_add_f.setString(12, f.md5);//f_md5

            this.cmd_add_f.setLong(13, f.lenLoc);//f_lenLoc

            this.cmd_add_f.setString(14, f.sizeLoc);//f_sizeLoc

            this.cmd_add_f.setLong(15, f.lenSvr);//f_lenSvr        

            this.cmd_add_f.setString(16, f.perSvr);//f_perSvr

            this.cmd_add_f.setBoolean(17, f.complete);//f_complete

            this.cmd_add_f.executeUpdate();

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }//

    }

   

    protected void save_folder(FileInf f)

    {

        try {

            this.cmd_add_fd.setString(1, f.id);//id

            this.cmd_add_fd.setString(2, f.pid);//pid

            this.cmd_add_fd.setString(3, f.pidRoot);//pidRoot

            this.cmd_add_fd.setString(4, f.nameSvr);//name

            this.cmd_add_fd.setInt(5, f.uid);//f_uid

            this.cmd_add_fd.setString(6, f.pathLoc);//pathLoc

            this.cmd_add_fd.setString(7, f.pathSvr);//pathSvr

            this.cmd_add_fd.setString(8, f.pathRel);//pathRel

            this.cmd_add_fd.setBoolean(9, f.complete);//complete

            this.cmd_add_fd.executeUpdate();

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    public void scan(FileInf inf, String root) throws IOException, SQLException

    {

        this.makeCmdF();

        this.makeCmdFD();

        this.GetAllFiles(inf, root);

        this.cmd_add_f.close();

        this.cmd_add_fd.close();

        this.con.close();

    }

}

 

分块上传,分块处理逻辑应该是最简单的逻辑了,up6已经将文件进行了分块,并且对每个分块数据进行了标识,这些标识包括文件块的索引,大小,偏移,文件MD5,文件块MD5(需要开启)等信息,服务端在接收这些信息后便可以非常方便的进行处理了。比如将块数据保存到分布式存储系统中

分块上传可以说是我们整个项目的基础,像断点续传、暂停这些都是需要用到分块。

分块这块相对来说比较简单。前端是采用了webuploader,分块等基础功能已经封装起来,使用方便。

借助webUpload提供给我们的文件API,前端就显得异常简单。

前台HTML模板

this.GetHtmlFiles = function()

{

     var acx = “”;

     acx += ‘<div class=”file-item” id=”tmpFile” name=”fileItem”>\

                <div class=”img-box”><img name=”file” src=”js/file.png”/></div>\

                   <div class=”area-l”>\

                       <div class=”file-head”>\

                            <div name=”fileName” class=”name”>HttpUploader程序开发.pdf</div>\

                            <div name=”percent” class=”percent”>(35%)</div>\

                            <div name=”fileSize” class=”size” child=”1″>1000.23MB</div>\

                    </div>\

                       <div class=”process-border”><div name=”process” class=”process”></div></div>\

                       <div name=”msg” class=”msg top-space”>15.3MB 20KB/S 10:02:00</div>\

                   </div>\

                   <div class=”area-r”>\

                    <span class=”btn-box” name=”cancel” title=”取消”><img name=”stop” src=”js/stop.png”/><div>取消</div></span>\

                    <span class=”btn-box hide” name=”post” title=”继续”><img name=”post” src=”js/post.png”/><div>继续</div></span>\

                       <span class=”btn-box hide” name=”stop” title=”停止”><img name=”stop” src=”js/stop.png”/><div>停止</div></span>\

                       <span class=”btn-box hide” name=”del” title=”删除”><img name=”del” src=”js/del.png”/><div>删除</div></span>\

                   </div>’;

     acx += ‘</div>’;

     acx += ‘<div class=”file-item” name=”folderItem”>\

                   <div class=”img-box”><img name=”folder” src=”js/folder.png”/></div>\

                   <div class=”area-l”>\

                       <div class=”file-head”>\

                            <div name=”fileName” class=”name”>HttpUploader程序开发.pdf</div>\

                            <div name=”percent” class=”percent”>(35%)</div>\

                            <div name=”fileSize” class=”size” child=”1″>1000.23MB</div>\

                    </div>\

                       <div class=”process-border top-space”><div name=”process” class=”process”></div></div>\

                       <div name=”msg” class=”msg top-space”>15.3MB 20KB/S 10:02:00</div>\

                   </div>\

                   <div class=”area-r”>\

                    <span class=”btn-box” name=”cancel” title=”取消”><img name=”stop” src=”js/stop.png”/><div>取消</div></span>\

                    <span class=”btn-box hide” name=”post” title=”继续”><img name=”post” src=”js/post.png”/><div>继续</div></span>\

                       <span class=”btn-box hide” name=”stop” title=”停止”><img name=”stop” src=”js/stop.png”/><div>停止</div></span>\

                       <span class=”btn-box hide” name=”del” title=”删除”><img name=”del” src=”js/del.png”/><div>删除</div></span>\

                   </div>’;

     acx += ‘</div>’;

     acx += ‘<div class=”files-panel” name=”post_panel”>\

                   <div name=”post_head” class=”toolbar”>\

                       <span class=”btn” name=”btnAddFiles”>选择多个文件</span>\

                       <span class=”btn” name=”btnAddFolder”>选择文件夹</span>\

                       <span class=”btn” name=”btnPasteFile”>粘贴文件和目录</span>\

                       <span class=”btn” name=”btnSetup”>安装控件</span>\

                   </div>\

                   <div class=”content” name=”post_content”>\

                       <div name=”post_body” class=”file-post-view”></div>\

                   </div>\

                   <div class=”footer” name=”post_footer”>\

                       <span class=”btn-footer” name=”btnClear”>清除已完成文件</span>\

                   </div>\

              </div>’;

     return acx;

};

 

分则必合。把大文件分片了,但是分片了就没有原本文件功能,所以我们要把分片合成为原本的文件。我们只需要把分片按原本位置写入到文件中去。因为前面原理那一部我们已经讲到了,我们知道分块大小和分块序号,我就可以知道该分块在文件中的起始位置。所以这里使用RandomAccessFile是明智的,RandomAccessFile能在文件里面前后移动。但是在andomAccessFile的绝大多数功能,已经被JDK1.4的NIO的“内存映射文件(memory-mapped files)”取代了。我在该项目中分别写了使用RandomAccessFile与MappedByteBuffer来合成文件。分别对应的方法是uploadFileRandomAccessFile和uploadFileByMappedByteBuffer。两个方法代码如下。

秒传功能

服务端逻辑

秒传功能,相信大家都体现过了,网盘上传的时候,发现上传的文件秒传了。其实原理稍微有研究过的同学应该知道,其实就是检验文件MD5,记录下上传到系统的文件的MD5,在一个文件上传前先获取文件内容MD5值或者部分取值MD5,然后在匹配系统上的数据。

Breakpoint-http实现秒传原理,客户端选择文件之后,点击上传的时候触发获取文件MD5值,获取MD5后调用系统一个接口(/index/checkFileMd5),查询该MD5是否已经存在(我在该项目中用redis来存储数据,用文件MD5值来作key,value是文件存储的地址。)接口返回检查状态,然后再进行下一步的操作。相信大家看代码就能明白了。

嗯,前端的MD5取值也是用了webuploader自带的功能,这还是个不错的工具。

控件计算完文件MD5后会触发md5_complete事件,并传值md5,开发者只需要处理这个事件即可,

 

断点续传

up6已经自动对断点续传进行了处理,不需要开发都再进行单独的处理。

在f_post.jsp中接收这些参数,并进行处理,开发者只需要关注业务逻辑,不需要关注其它的方面。

 

断点续传,就是在文件上传的过程中发生了中断,人为因素(暂停)或者不可抗力(断网或者网络差)导致了文件上传到一半失败了。然后在环境恢复的时候,重新上传该文件,而不至于是从新开始上传的。

前面也已经讲过,断点续传的功能是基于分块上传来实现的,把一个大文件分成很多个小块,服务端能够把每个上传成功的分块都落地下来,客户端在上传文件开始时调用接口快速验证,条件选择跳过某个分块。

实现原理,就是在每个文件上传前,就获取到文件MD5取值,在上传文件前调用接口(/index/checkFileMd5,没错也是秒传的检验接口)如果获取的文件状态是未完成,则返回所有的还没上传的分块的编号,然后前端进行条件筛算出哪些没上传的分块,然后进行上传。

当接收到文件块后就可以直接写入到服务器的文件中

这是文件夹上传完后的效果

 

这是文件夹上传完后在服务端的存储结构

 

参考文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

]]>
Java Web 项目的文件/文件夹上传下载 http://blog.ncmem.com/wordpress/2019/12/17/java-web-%e9%a1%b9%e7%9b%ae%e7%9a%84%e6%96%87%e4%bb%b6-%e6%96%87%e4%bb%b6%e5%a4%b9%e4%b8%8a%e4%bc%a0%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 08:35:56 +0000 http://blog.ncmem.com/wordpress/?p=1629 继续阅读 Java Web 项目的文件/文件夹上传下载]]> 相关资料:解决方案,白皮书,产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,控件包,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

        

产品交流群:泽优Web大文件上传控件

 

视频教程:https://www.bilibili.com/video/BV1uj411V75m/?vd_source=d1843c7f8c164416779b5188178bad8c

导入项目:
导入到Eclipse:http://www.ncmem.com/doc/view.aspx?id=9da9c7c2b91b40b7b09768eeb282e647
导入到IDEA:http://www.ncmem.com/doc/view.aspx?id=9fee385dfc0742448b56679420f22162
springboot统一配置:http://www.ncmem.com/doc/view.aspx?id=7768eec9284b48e3abe08f032f554ea2

 

环境:Windows + Tomcat8.0+

版本:6.5.41

示例:https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.41/

 

NOSQL

NOSQL示例不需要任何配置,可以直接访问测试

 

创建数据表

选择对应的数据表脚本,这里以SQL为例

 

修改数据库连接信息

访问页面进行测试

 

文件存储路径

up6/upload/年/月/日/guid/filename

 

数据库记录  

相关问题:
1.javax.servlet.http.HttpServlet错误
2.项目无法发布到tomcat
3.md5计算完毕后卡住
4.服务器找不到config.json文件

相关参考:

文件保存位置

 

免费下载产品源代码-泽优全平台开源大文件传输解决方案(up6-down2)

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
JavaScript开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/javascript%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 07:34:09 +0000 http://blog.ncmem.com/wordpress/?p=1627 继续阅读 JavaScript开发——文件夹的上传和下载]]> 相关资料:解决方案,白皮书,产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

        

产品交流群:泽优Web大文件上传控件

视频教程:https://www.bilibili.com/video/BV1jm4y127Ut/?vd_source=d1843c7f8c164416779b5188178bad8c

环境:vue2-cli

示例:https://gitee.com/xproer/up6-vue-cli

 

1.下载示例

 

将up6组件复制到项目中

示例中已经包含此目录

 

1.引入up6组件

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

3.处理事件

 

启动测试

 

启动成功

 

访问测试页面

 

效果

 

数据库

 

下载产品源代码-泽优全平台开源大文件上传控件(up6)

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
JS开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/js%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 06:32:06 +0000 http://blog.ncmem.com/wordpress/?p=1625 继续阅读 JS开发——文件夹的上传和下载]]> 相关资料:解决方案,白皮书,产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

        

产品交流群:泽优Web大文件上传控件

视频教程:https://www.bilibili.com/video/BV1jm4y127Ut/?vd_source=d1843c7f8c164416779b5188178bad8c

环境:vue2-cli

示例:https://gitee.com/xproer/up6-vue-cli

 

1.下载示例

 

将up6组件复制到项目中

示例中已经包含此目录

 

1.引入up6组件

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

3.处理事件

 

启动测试

 

启动成功

 

访问测试页面

 

效果

 

数据库

 

下载产品源代码-泽优全平台开源大文件上传控件(up6)

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
B/S开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/b-s%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 05:46:29 +0000 http://blog.ncmem.com/wordpress/?p=1623 继续阅读 B/S开发——文件夹的上传和下载]]> 相关资料:产品首页,白皮书,控件包,白皮书(图文版),产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

标杆案例:中国港湾中国中车中国石油中国石化,长江电力中信证券上海通用一汽大众,沈阳自动化研究所,

解决方案:党政央企国防军工房地产档案管理教育医疗工程管理企业文件传输解决方案

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,jsp-eclipse-sm4加密存储,jsp-springboot-sm4加密存储,asp.net-sm4加密存储

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

       

产品交流群:泽优Web大文件上传控件


视频教程:
https://www.bilibili.com/video/BV1jm4y127Ut/?vd_source=d1843c7f8c164416779b5188178bad8c

 

1.下载示例

https://gitee.com/xproer/up6-vue-cli

 

 

up6组件复制到项目中

示例中已经包含此目录

 

 

1.引入up6组件

 

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

 

3.处理事件

 

 

启动测试

 

 

启动成功

 

 

效果

 

 

数据库

 

 

大文件上传控件(up6

个人版:http://www.ncmem.com/webapp/up6/purchase.aspx

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
php web开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/php-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 02:40:27 +0000 http://blog.ncmem.com/wordpress/?p=1621 继续阅读 php web开发——文件夹的上传和下载]]> 相关资料:产品首页,控件包,白皮书,白皮书(图文版),产品介绍,产品比较,控件源码文档,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件

解决方案:党政央企国防军工房地产档案管理教育医疗工程管理企业文件传输解决方案

标杆案例:中国港湾中国中车中国石油中国石化,长江电力中信证券上海通用一汽大众,沈阳自动化研究所,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,jsp-eclipse-sm4加密存储,jsp-springboot-sm4加密存储,asp.net-sm4加密存储

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

       

产品交流群:泽优Web大文件上传控件

视频教程:https://www.ixigua.com/7201113912295883264

 

版本:6.5.41

代码:https://gitee.com/xproer/up6-php/tree/6.5.41/

 

安装环境

PHP:7.2.14

调整块大小

 

NOSQL

NOSQL不需要任何配置,可以直接访问测试

SQL

创建数据库

您可以直接复制脚本进行创建

 

配置数据库连接

 

6.安装依赖

访问页面进行测试

 

数据表中的数据

相关参考:

文件保存位置

php5教程

 

大文件上传控件(up6)

个人版:http://www.ncmem.com/webapp/up6/purchase.aspx

政企版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=ent

年费版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=year

OEM版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=oem

源码版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=code

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

 

大文件上传下载控件(up6-down2)

政企版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=ent

年费版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=year

OEM版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=oem

源码版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=code

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
asp.net web开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/asp-net-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 02:02:03 +0000 http://blog.ncmem.com/wordpress/?p=1619 继续阅读 asp.net web开发——文件夹的上传和下载]]> 相关资料:解决方案,白皮书,产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

        

产品交流群:泽优Web大文件上传控件

 

视频教程:https://www.bilibili.com/video/BV1Vs4y1b7yh/?vd_source=d1843c7f8c164416779b5188178bad8c

 

框架:.NET Framework 4.7.2

版本:6.5.41

示例:https://gitee.com/xproer/up6-asp-net/tree/6.5.41/

 

安装.NET Framework 4.7.2

https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472

百度网盘:https://pan.baidu.com/s/13CGIHrRDSc1pPc-gR8miog?pwd=bnbl

 

框架选择4.7.2

 

添加3rd引用

 

编译项目

 

NOSQL

NOSQL无需任何配置可直接访问页面进行测试

 

SQL

使用IIS

大文件上传测试推荐使用IIS以获取更高性能。

使用IIS Express

小文件上传测试可以使用IIS Express

创建数据库

配置数据库连接信息

 

检查数据库配置

点击“清空数据库”链接,测试数据库配置是否正确

 

访问页面进行测试

 

检查数据库数据

 

检查上传的文件

 

相关参考:

文件保存位置

免费下载产品源代码-泽优全平台开源大文件传输解决方案(up6-down2)

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
Java web开发——文件夹的上传和下载 http://blog.ncmem.com/wordpress/2019/12/17/java-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e5%a4%b9%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Tue, 17 Dec 2019 01:28:06 +0000 http://blog.ncmem.com/wordpress/?p=1617 继续阅读 Java web开发——文件夹的上传和下载]]> 我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。

这次项目的需求:

支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,ie8,ie9,Chrome,Firefox,360安全浏览器,并且刷新浏览器后仍然能够续传,重启浏览器(关闭浏览器后再打开)仍然能够继续上传,重启电脑后仍然能够上传

支持文件夹的上传,要求服务端能够保留层级结构,并且能够续传。需要支持10万个以上的文件夹上传。

支持低版本的系统和浏览器,因为这个项目的最终运行环境在政府,政府的配置都一般,职员都是办公用,内存都不大,基本上以Windows XP的系统为主。

 

1、介绍enctype

enctype 属性规定发送到服务器之前应该如何对表单数据进行编码。

enctype作用是告知服务器请求正文的MIME类型(请求消息头content-type的作用一样)

1、1 enctype的取值有三种

描述

application/x-www-form-urlencoded

在发送前编码所有字符(默认)

multipart/form-data

不对字符编码。每一个表单项分割为一个部件

text/plain

空格转换为 “+” 加号,但不对特殊字符编码。

1. 当enctype=’application/x-www-form-urlencoded’

2.当enctype=’multipart/form-data’

 

通过观察发现这个的请求体就发生了变化。这种请求体被称之为多部件请求体。

什么是多部件请求体:就是把每一个表单项分割为一个部件。

以请求头的content-type的boundary后面的一串随机字符串作为分割标识

普通表单项:

//name的意思是文本框里面name的属性值,而admin是我们输入的文本值

Content-Disposition: form-data; name=”username”

admin

文件表单项

//filename的意思是:我们上传的文件名称,content-Type的意思是:MIME类型,asdasdas的意思是:文件里面的内容

Content-Disposition: form-data; name=”upload”; filename=”a.txt”

Content-Type: text/plain

asdasdas

3. 当enctype=’text/plain’

 

w3c称:空格会变成”+”加号,但是我这里没有发现,只有当get请求的时候,空格会变成”+”号

 

进入正题

完成上传需要满足3个必要的条件

提供form表单,method必须是post,因为get请求的传输数据一般为2kb,不同浏览器不一样。

form表单属性enctype的必须是multipart/form-data

提供input type=”file”类的上传输入域

大致实现原理:当enctype的值是multipart/form-data时,浏览器会把每个表单项进行分割,分割成不同的部件,以boundary的值为分割标识,这个标识的字符串是随机生成的,最后一个表单项的分割标识字符串末尾会多两个”- -“,代表结束。服务端用request.getHeader(“content-type”)获取分割字符串,然后进行解析。

 

 

代码实现

一、开发环境搭建

准备两个第三方jar包

commons-io包

commons-upload包

所有依赖包

 

代码实现

<%@ page language=”java” import=”up6.DBFile” pageEncoding=”UTF-8″%>

<%@ page contentType=”text/html;charset=UTF-8″%>

<%@ page import=”up6.FileBlockWriter” %>

<%@ page import=”up6.XDebug” %>

<%@ page import=”up6.*” %>

<%@ page import=”up6.biz.*” %>

<%@ page import=”org.apache.commons.fileupload.FileItem” %>

<%@ page import=”org.apache.commons.fileupload.FileItemFactory” %>

<%@ page import=”org.apache.commons.fileupload.FileUploadException” %>

<%@ page import=”org.apache.commons.fileupload.disk.DiskFileItemFactory” %>

<%@ page import=”org.apache.commons.fileupload.servlet.ServletFileUpload” %>

<%@ page import=”org.apache.commons.lang.*” %>

<%@ page import=”java.net.URLDecoder”%>

<%@ page import=”java.util.Iterator”%>

<%@ page import=”net.sf.json.JSONObject”%>

<%@ page import=”java.util.List”%>

<%

out.clear();

String uid             = request.getHeader(“uid”);//

String id              = request.getHeader(“id”);

String lenSvr      = request.getHeader(“lenSvr”);

String lenLoc      = request.getHeader(“lenLoc”);

String blockOffset = request.getHeader(“blockOffset”);

String blockSize   = request.getHeader(“blockSize”);

String blockIndex  = request.getHeader(“blockIndex”);

String blockMd5        = request.getHeader(“blockMd5”);

String complete        = request.getHeader(“complete”);

String pathSvr         = “”;

 

//参数为空

if(  StringUtils.isBlank( uid )

     || StringUtils.isBlank( id )

     || StringUtils.isBlank( blockOffset ))

{

     XDebug.Output(“param is null”);return;

}

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory = new DiskFileItemFactory();  

ServletFileUpload upload = new ServletFileUpload(factory);

List files = null;

try {files = upload.parseRequest(request);}

catch (FileUploadException e)

{out.println(“read file data error:” + e.toString());return;}

 

FileItem rangeFile = null;

Iterator fileItr = files.iterator();

while (fileItr.hasNext())

{

     rangeFile = (FileItem) fileItr.next();

     if(StringUtils.equals( rangeFile.getFieldName(),”pathSvr”))

     {

         pathSvr = rangeFile.getString();

         pathSvr = PathTool.url_decode(pathSvr);

     }

}

 

boolean verify = false;

String msg = “”;

String md5Svr = “”;

long blockSizeSvr = rangeFile.getSize();

if(!StringUtils.isBlank(blockMd5)){md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());}

verify = Integer.parseInt(blockSize) == blockSizeSvr;

if(!verify){ msg = “block size error sizeSvr:” + blockSizeSvr + “sizeLoc:” + blockSize;}

if(verify && !StringUtils.isBlank(blockMd5))

{

     verify = md5Svr.equals(blockMd5); if(!verify) msg = “block md5 error”;

}

if(verify)

{

     FileBlockWriter res = new FileBlockWriter();

     if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));

     res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

     up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));

    

     JSONObject o = new JSONObject();

     o.put(“msg”, “ok”);

     o.put(“md5”, md5Svr); 

     o.put(“offset”, blockOffset);

     msg = o.toString();

}

rangeFile.delete();

out.write(msg);

%>

下载的必须条件

两个头一个流

content-type

Content-Type是返回消息中非常重要的内容,表示文档内容属于什么MIME类型。

浏览器会根据Content-Type来决定如何显示返回的消息体内容。

默认值是text/html

可以使用request.getServletContext().getMimeType(“文件名”)获取MIME类型。

Content-Disposition

Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。

默认值是inline,表示在浏览器窗口中打开。

服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器 中显示。

如果需要提示用户保存,利用Content-Disposition进行一下处理,关键在于一定要加上attachment。

例如:Content-Disposition:attachment;filename=xxx,浏览器就会激活下载框对话框, attachment 表示附件, filname 后面跟随的是显示在下载框中的文件名称。

下载就是向客户端响应字节数据! 将一个文件变成字节数组, 使用 response.getOutputStream()

来响应给浏览器。

代码如下,此代码已经实现了断点续传功能,用户在下载过程可以暂停,和继续下载,对服务器造成的压力也比较小。

String fid             = request.getHeader(“id”);

String blockIndex = request.getHeader(“blockIndex”);//基于1

String blockOffset     = request.getHeader(“blockOffset”);//块偏移,相对于整个文件

String blockSize   = request.getHeader(“blockSize”);//块大小(当前需要下载的大小)

String pathSvr         = request.getHeader(“pathSvr”);//文件在服务器的位置

pathSvr            = PathTool.url_decode(pathSvr);

 

if (  StringUtils.isBlank(fid)

     ||StringUtils.isBlank(blockIndex)

     ||StringUtils.isEmpty(blockOffset)

     ||StringUtils.isBlank(blockSize)

     ||StringUtils.isBlank(pathSvr))

{

     response.setStatus(500);

     response.setHeader(“err”,”参数为空”);

     return;

}

File f = new File(pathSvr);

//文件不存在

if(!f.exists())

{

     response.setStatus(500);

     OutputStream os = response.getOutputStream();

     System.out.println(String.format(“%s 文件不存在”,pathSvr));

     os.close();

     return;

}

long fileLen = f.length();

 

response.setContentType(“application/x-download”);

response.setHeader(“Pragma”,”No-cache”); 

response.setHeader(“Cache-Control”,”no-cache”);

response.addHeader(“Content-Length”,blockSize); 

response.setDateHeader(“Expires”, 0);

 

OutputStream os = response.getOutputStream();

try

{

     RandomAccessFile raf = new RandomAccessFile(pathSvr,”r”);

    

     int readToLen = Integer.parseInt(blockSize);

     int readLen = 0;

     raf.seek( Long.parseLong(blockOffset) );//定位索引

     byte[] data = new byte[1048576];

    

     while( readToLen > 0 )

     {

         readLen = raf.read(data,0,Math.min(1048576,readToLen) );

         readToLen -= readLen;

         os.write(data, 0, readLen);

        

     }

     os.flush();

     os.close();  

     raf.close();

     os = null;

     response.flushBuffer();

    

     out.clear();

     out = pageContext.pushBody();

}

catch(Exception e)

{

     response.setStatus(500);

     os.close();

     out.close();

     e.printStackTrace();

}

finally

{   

     if(os != null)

     {

         os.close();       

         os = null;

     }

     out.clear();

     out = pageContext.pushBody();

}%>

 

加载文件列表,在下载列表中显示出来

后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

]]>
web开发——文件的上传和下载 http://blog.ncmem.com/wordpress/2019/12/16/web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Mon, 16 Dec 2019 09:58:02 +0000 http://blog.ncmem.com/wordpress/?p=1614 继续阅读 web开发——文件的上传和下载]]> 相关资料:产品首页,白皮书,控件包,白皮书(图文版),产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

标杆案例:中国港湾中国中车中国石油中国石化,长江电力中信证券上海通用一汽大众,沈阳自动化研究所,

解决方案:党政央企国防军工房地产档案管理教育医疗工程管理企业文件传输解决方案

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,jsp-eclipse-sm4加密存储,jsp-springboot-sm4加密存储,asp.net-sm4加密存储

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

       

产品交流群:泽优Web大文件上传控件


视频教程:
https://www.bilibili.com/video/BV1jm4y127Ut/?vd_source=d1843c7f8c164416779b5188178bad8c

 

1.下载示例

https://gitee.com/xproer/up6-vue-cli

 

 

up6组件复制到项目中

示例中已经包含此目录

 

 

1.引入up6组件

 

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

 

3.处理事件

 

 

启动测试

 

 

启动成功

 

 

效果

 

 

数据库

 

 

大文件上传控件(up6

个人版:http://www.ncmem.com/webapp/up6/purchase.aspx

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
asp.net web开发——文件的上传和下载 http://blog.ncmem.com/wordpress/2019/12/16/asp-net-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Mon, 16 Dec 2019 09:37:38 +0000 http://blog.ncmem.com/wordpress/?p=1612 继续阅读 asp.net web开发——文件的上传和下载]]> HTML部分 

<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”index.aspx.cs” Inherits=”up6.index” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >

<head>

     <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />

    <title>up6-多标签演示页面</title>

    <link href=”js/up6.css” type=”text/css” rel=”Stylesheet” charset=”gb2312″/>

    <script type=”text/javascript” src=”js/jquery-1.4.min.js”></script>

    <script type=”text/javascript” src=”js/json2.min.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.config.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.app.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.edge.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.file.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.folder.js” charset=”utf-8″></script>

    <script type=”text/javascript” src=”js/up6.js” charset=”utf-8″></script>

    <script language=”javascript” type=”text/javascript”>

        var cbMgr = new HttpUploaderMgr();

        cbMgr.event.md5Complete = function (obj, md5) { /*alert(md5);*/ };

        cbMgr.event.fileComplete = function (obj) { /*alert(obj.fileSvr.pathSvr);*/ };

        cbMgr.event.queueComplete = function () { $(document.body).append(“队列完成<br/>”); }

        cbMgr.event.addFdError = function (jv) { alert(“本地路径不存在:” + jv.path); };

        cbMgr.event.scanComplete = function (obj) { /*alert(obj.folderSvr.pathLoc);*/ };

        cbMgr.Config[“Cookie”] = ‘ASP.NET_SessionId=<%=Session.SessionID%>’;

        cbMgr.Config.Fields[“uid”] = 0;

 

        $(function ()

        {

            cbMgr.load_to(“FilePanel”);

            //上传指定文件

            $(“#btnUpF”).click(function () {

                var path = $(“#filePath”).val();

                cbMgr.app.addFile({ pathLoc: path });

            });

            //上传指定目录

            $(“#btnUpFd”).click(function () {

                var path = $(“#folderPath”).val();

                cbMgr.app.addFolder({ pathLoc: path });

            });

        });

    </script>

</head>

<body>

    <p>up6多标签上传演示页面</p>

    <p><a href=”db/clear.aspx” target=”_blank”>清空数据库</a></p>

    <p><a href=”filemgr/index.aspx” target=”_blank”>文件管理器演示</a></p>

    <p><a href=”index2.aspx” target=”_blank”>单面板演示</a></p>

    <p><a href=”down2/index.htm” target=”_blank”>打开下载页面</a></p>

    <p><a href=”index-single.htm” target=”_blank”>单文件上传演示</a></p>

    <p>

        文件路径:<input id=”filePath” type=”text” size=”50″ value=”D:\\360safe-inst.exe” />&nbsp;

        <input id=”btnUpF” type=”button” value=”上传本地文件” />

    </p>

    <p>

        目录路径:<input id=”folderPath” type=”text” size=”50″ value=”C:\\Users\\Administrator\\Desktop\\test” />&nbsp;

        <input id=”btnUpFd” type=”button” value=”上传本地目录” />

    </p>

     <div id=”FilePanel”></div>

    <div id=”msg”></div>

</body>

</html>

 

代码部分 

using  System; 

using  System.Collections; 

using  System.ComponentModel; 

using  System.Data; 

using  System.Drawing; 

using  System.Web; 

using  System.Web.SessionState; 

using  System.Web.UI; 

using  System.Web.UI.WebControls; 

using  System.Web.UI.HtmlControls; 

 

namespace  WebPortal 

           ///  <summary> 

           ///  UpLoad  的摘要说明。 

           ///  实现多文件上传 

           ///  </summary> 

           public  class  Upload  :  System.Web.UI.Page 

           { 

                       protected  System.Web.UI.WebControls.Button  UploadButton; 

                       protected  System.Web.UI.WebControls.Label  strStatus; 

 

                       private  void  Page_Load(object  sender,  System.EventArgs  e) 

                       { 

                                   ///  在此处放置用户代码以初始化页面 

                                   if  (this.IsPostBack)  this.SaveImages(); 

                       } 

 

                       private  Boolean  SaveImages() 

                       { 

                                   ///’遍历File表单元素 

                                   HttpFileCollection  files    =  HttpContext.Current.Request.Files; 

 

                                   ///  ‘状态信息 

                                   System.Text.StringBuilder  strMsg  =  new  System.Text.StringBuilder(); 

                                   strMsg.Append(“上传的文件分别是:<hr  color=red>”); 

                                   try 

                                   { 

                                               for(int  iFile  =  0;  iFile  <  files.Count;  iFile++) 

                                               { 

                                                           ///’检查文件扩展名字  

                                                           HttpPostedFile  postedFile  =  files[iFile]; 

                                                           string  fileName,  fileExtension; 

                                                           fileName  =  System.IO.Path.GetFileName(postedFile.FileName); 

                                                           if  (fileName  !=  “”) 

                                                           { 

                                                                       fileExtension  =  System.IO.Path.GetExtension(fileName); 

                                                                       strMsg.Append(“上传的文件类型:”  +  postedFile.ContentType.ToString()  +  “<br>”); 

                                                                       strMsg.Append(“客户端文件地址:”  +  postedFile.FileName  +  “<br>”); 

                                                                       strMsg.Append(“上传文件的文件名:”  +  fileName  +  “<br>”); 

                                                                       strMsg.Append(“上传文件的扩展名:”  +  fileExtension  +  “<br><hr>”); 

                                                                       ///’可根据扩展名字的不同保存到不同的文件夹 

                                                                       ///注意:可能要修改你的文件夹的匿名写入权限。 

                                                                       postedFile.SaveAs(System.Web.HttpContext.Current.Request.MapPath(“images/”)  +  fileName); 

                                                           } 

                                               } 

                                               strStatus.Text  =  strMsg.ToString(); 

                                               return  true; 

                                   } 

                                   catch(System.Exception  Ex) 

                                   { 

                                               strStatus.Text  =  Ex.Message; 

                                               return  false; 

                                   } 

                       } 

                       #region  Web  窗体设计器生成的代码 

                       override  protected  void  OnInit(EventArgs  e) 

                       { 

                                   // 

                                   //  CODEGEN:  该调用是  ASP.NET  Web  窗体设计器所必需的。 

                                   // 

                                   InitializeComponent(); 

                                   base.OnInit(e); 

                       } 

 

                       ///  <summary> 

                       ///  设计器支持所需的方法  –  不要使用代码编辑器修改 

                       ///  此方法的内容。 

                       ///  </summary> 

                       private  void  InitializeComponent() 

                       {         

                                   this.ID  =  “Upload”; 

                                   this.Load  +=  new  System.EventHandler(this.Page_Load); 

 

                       } 

                       #endregion 

           }

}

 

选择文件夹

 

js部分

后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/07/java超大文件上传与下载/

]]>
.net web开发——文件的上传和下载 http://blog.ncmem.com/wordpress/2019/12/16/net-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Mon, 16 Dec 2019 08:03:46 +0000 http://blog.ncmem.com/wordpress/?p=1610 继续阅读 .net web开发——文件的上传和下载]]> 以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载。

 

准备文件上传的API

 

#region 文件上传  可以带参数

        [HttpPost(“upload”)]

        public JsonResult uploadProject(IFormFile file, string userId)

        {

            if (file != null)

            {

                var fileDir = “D:\\aaa”;

                if (!Directory.Exists(fileDir))

                {

                    Directory.CreateDirectory(fileDir);

                }

                //文件名称

                string projectFileName = file.FileName;

 

                //上传的文件的路径

                string filePath = fileDir + $@”\{projectFileName}”;

                using (FileStream fs = System.IO.File.Create(filePath))

                {

                    file.CopyTo(fs);

                    fs.Flush();

                }

                return Json(“ok”);

            }else{

                return Json(“no”);

            }

        }

        #endregion

前端vue上传组件  ( 利用Form表单上传 )

 

<template>

<div>

    <form>

        <input type=”text” value=”” v-model=”projectName” placeholder=”请输入项目名称”>

        <input type=”file” v-on:change=”getFile($event)”>

        <button v-on:click=”submitForm($event)”>上传</button>

    </form>

</div>

</template>

 

<script>

///这个组件是用于上传bdls文件的组件

export default {

  data() {

    return {

      uploadURL: “/Home/Upload”,

      projectName: “”,

      file: “”

    };

  },

  methods: {

    getFile(event) {

      this.file = event.target.files[0];

      console.log(this.file);

    },

    submitForm(event) {

      event.preventDefault();

      let formData = new FormData();

      formData.append(“file”, this.file);

 

      let config = {

        headers: {

          “Content-Type”: “multipart/form-data”

        }

      };

 

      this.$http

        .post(this.uploadURL, formData, config)

        .then(function(response) {

          if (response.status === 200) {

            console.log(response.data);

          }

        });

    }

  }

};

</script>

 

<style lang=”scss” scoped>

</style>

用 element-ui 的 Upload组件上传文件

 

http://element-cn.eleme.io/#/zh-CN/component/upload

 

<template>

<div>

    <el-upload

      class=”upload-css”

      :file-list=”uploadFiles”

      ref=”upload”

      :on-success=”upLoadSuccess”

      :on-error=”upLoadError”

      :action=”uploadURL”

      :auto-upload=”false”>

        <el-button slot=”trigger” size=”small” type=”primary”>选取文件</el-button>

        <el-button style=”margin-left: 10px;” size=”small” type=”success” @click=”submitUpload”>上传到服务器</el-button>

    </el-upload>

</div>

</template>

 

<script>

import Vue from “vue”;

import { Upload, Button } from “element-ui”;

Vue.use(Upload);

Vue.use(Button);

 

export default {

  props: [],

  data() {

    return {

      projectName: “”,

      //uploadURL: “/project/upload?a=1”,

      uploadFiles: [] //上传的文件列表

    };

  },

  computed: {

    //文件的上传路径

    //附带用户id和项目名称

    uploadURL: function() {

      //var userId = this.$store.state.userId;

      return “/project/upload?userId=” + 1;

    }

  },

  methods: {

    //文件上传

    submitUpload() {

      this.$refs.upload.submit();

    },

    //文件上传成功时的钩子

    upLoadSuccess(response, file, fileList) {

      if (response == “ok”) {

        console.log(response + “已上传” + file);

        console.log(“项目添加成功”);

      } else {

        console.log(“项目添加失败”);

      }

    },

    //文件上传失败时的钩子

    upLoadError(response, file, fileList) {

      console.log(“项目添加失败”);

    }

  }

};

</script>

 

<style lang=”scss” scoped>

</style>

文件下载

普通的文件下载方式是访问一个后台文件流地址,直接生成对应的文件,下载即可,地址栏中也可携带一些控制参数,但是无法通过header传递参数。

 

两种文件下载方式,一种是,直接返回file文件,利用浏览器的下载功能。但是这种没有发现可以在发送请求的时候携带token;另一种是利用 Axios 发送下载文件的请求,可以设置header头,可以携带token ,但是response-type是blob类型的。

 

第一种:

后端API:

 

public FileResult downloadRequest()

        {

            //var addrUrl = webRootPath + “/upload/thumb.jpg”;

            var addrUrl = “D:/aaa/thumb.jpg”;

 

            var stream = System.IO.File.OpenRead(addrUrl);

 

            string fileExt = Path.GetExtension(“thumb.jpg”);

 

            //获取文件的ContentType

 

            var provider = new FileExtensionContentTypeProvider();

 

            var memi = provider.Mappings[fileExt];

 

            return File(stream, memi, Path.GetFileName(addrUrl));

        }

前端利用浏览器的功能url直接返回文件

 

下载文件…

 

downloadRequest() {   

    let url = “Home/downloadRequest”; //可以在路径中传递参数

    window.location.href = url;

 },

第二种

后端api ,两个api的返回类型不同,asp.net core 文件下载常用的有FileResult 、FileContentResult 、 FileStreamResult。

 

public FileContentResult downloadRequest1()

        {

            //string webRootPath = _hostingEnvironment.WebRootPath;

            //var addrUrl = webRootPath + “/upload/thumb.jpg”;

            var addrUrl = “D:/aaa/wyy.exe”;

 

            /*var stream = System.IO.File.OpenRead(addrUrl);

 

            string fileExt = Path.GetExtension(“thumb.jpg”);

 

            //获取文件的ContentType

 

            var provider = new FileExtensionContentTypeProvider();

 

            var memi = provider.Mappings[fileExt];

 

            return File(stream, memi, Path.GetFileName(addrUrl));*/

 

            //return stream;

            byte[] fileBytes = System.IO.File.ReadAllBytes(addrUrl);

            string fileName = “wyy.exe”;

            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName); //关键语句

        }

前端页面

 

blob(用来存储二进制大文件)

 

<el-button type=”primary” v-on:click=”downloadRequest1″>下载文件11</el-button>

    downloadRequest1() {

      axios({

        // 用axios发送post请求

        method: “post”,

        url: “Home/downloadRequest1”, // 请求地址 ,也可以传递参数

        headers: {

          //可以自定义header

          gggg: “gggggggggggggggggggggggggggggggggggggggggggggggggggg”  //可以携带token

        },

        responseType: “blob” // 表明返回服务器返回的数据类型

      }).then(res => {

        // 处理返回的文件流

        //主要是将返回的data数据通过blob保存成文件

        var content = res.data;

        var blob = new Blob([content]);

        var fileName = “wyy.exe”; //要保存的文件名称

        if (“download” in document.createElement(“a”)) {

          // 非IE下载

          var elink = document.createElement(“a”);

          elink.download = fileName;

          elink.style.display = “none”;

          elink.href = URL.createObjectURL(blob);

          document.body.appendChild(elink);

          elink.click();

          URL.revokeObjectURL(elink.href); // 释放URL 对象

          document.body.removeChild(elink);

        } else {

          // IE10+下载

          navigator.msSaveBlob(blob, fileName);

        }

        console.log(res);

      });

    }

第三种

就是用用up6控件,此控件支持mac、windos、Linux,因为太长就不发了,详细可以参考这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/asp-net%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e4%b8%8b%e8%bd%bd/

 

]]>
php web开发——文件的上传和下载 http://blog.ncmem.com/wordpress/2019/12/16/php-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Mon, 16 Dec 2019 07:22:58 +0000 http://blog.ncmem.com/wordpress/?p=1608 继续阅读 php web开发——文件的上传和下载]]> 相关资料:产品首页,控件包,白皮书,白皮书(图文版),产品介绍,产品比较,控件源码文档,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件

解决方案:党政央企国防军工房地产档案管理教育医疗工程管理企业文件传输解决方案

标杆案例:中国港湾中国中车中国石油中国石化,长江电力中信证券上海通用一汽大众,沈阳自动化研究所,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,jsp-eclipse-sm4加密存储,jsp-springboot-sm4加密存储,asp.net-sm4加密存储

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

       

产品交流群:泽优Web大文件上传控件

视频教程:https://www.bilibili.com/video/BV1im4y117ht/?vd_source=d1843c7f8c164416779b5188178bad8c

版本:6.5.41

代码:https://gitee.com/xproer/up6-php/tree/6.5.41/

 

安装环境

PHP:7.2.14

调整块大小

 

NOSQL

NOSQL不需要任何配置,可以直接访问测试

SQL

创建数据库

您可以直接复制脚本进行创建

 

配置数据库连接

 

6.安装依赖

访问页面进行测试

 

数据表中的数据

相关参考:

文件保存位置

php5教程

 

大文件上传控件(up6)

个人版:http://www.ncmem.com/webapp/up6/purchase.aspx

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

]]>
Java web开发——文件的上传和下载 http://blog.ncmem.com/wordpress/2019/12/16/java-web%e5%bc%80%e5%8f%91-%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/ Mon, 16 Dec 2019 06:41:12 +0000 http://blog.ncmem.com/wordpress/?p=1606 继续阅读 Java web开发——文件的上传和下载]]> 一、 功能性需求与非功能性需求

要求操作便利,一次选择多个文件和文件夹进行上传;
支持PC端全平台操作系统,Windows,Linux,Mac

支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。

支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同。

支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验;
支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。

支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留进度。

支持文件夹结构管理,支持新建文件夹,支持文件夹目录导航

交互友好,能够及时反馈上传的进度;

服务端的安全性,不因上传文件功能导致JVM内存溢出影响其他功能使用;

最大限度利用网络上行带宽,提高上传速度;


二、 设计分析

对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传

从上传的效率来看,利用多线程并发上传能够达到最大效率。


三、解决方案:

文件上传页面的前端可以选择使用一些比较好用的上传组件,例如百度的开源组件WebUploader,泽优软件的up6,这些组件基本能满足文件上传的一些日常所需功能,如异步上传文件,文件夹,拖拽式上传,黏贴上传,上传进度监控,文件缩略图,甚至是大文件断点续传,大文件秒传。 

在web项目中上传文件夹现在已经成为了一个主流的需求。在OA,或者企业ERP系统中都有类似的需求。上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便。能够提供更高级的应用支撑。

文件夹数据表结构

CREATE TABLE IF NOT EXISTS `up6_folders` (

  `f_id`               char(32) NOT NULL ,

  `f_nameLoc`               varchar(255) default ”,

  `f_pid`                   char(32) default ”,

  `f_uid`                   int(11) default ‘0’,

  `f_lenLoc`           bigint(19) default ‘0’,

  `f_sizeLoc`               varchar(50) default ‘0’,

  `f_pathLoc`               varchar(255) default ”,

  `f_pathSvr`               varchar(255) default ”,

  `f_pathRel`               varchar(255) default ”,

  `f_folders`               int(11) default ‘0’,

  `f_fileCount`        int(11) default ‘0’,

  `f_filesComplete`    int(11) default ‘0’,

  `f_complete`              tinyint(1) default ‘0’,

  `f_deleted`               tinyint(1) default ‘0’,

  `f_time`                  timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

  `f_pidRoot`               char(32) default ”,

  PRIMARY KEY  (`f_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

文件数据表结构

CREATE TABLE IF NOT EXISTS `up6_files` (

  `f_id`               char(32) NOT NULL,

  `f_pid`                   char(32) default ”,        /*父级文件夹ID*/

  `f_pidRoot`               char(32) default ”,        /*根级文件夹ID*/

  `f_fdTask`           tinyint(1) default ‘0’,     /*是否是一条文件夹信息*/

  `f_fdChild`               tinyint(1) default ‘0’,     /*是否是文件夹中的文件*/

  `f_uid`                   int(11) default ‘0’,

  `f_nameLoc`               varchar(255) default ”,    /*文件在本地的名称(原始文件名称)*/

  `f_nameSvr`               varchar(255) default ”,    /*文件在服务器的名称*/

  `f_pathLoc`               varchar(512) default ”,    /*文件在本地的路径*/

  `f_pathSvr`               varchar(512) default ”,    /*文件在远程服务器中的位置*/

  `f_pathRel`               varchar(512) default ”,

  `f_md5`                   varchar(40) default ”,     /*文件MD5*/

  `f_lenLoc`           bigint(19) default ‘0’,     /*文件大小*/

  `f_sizeLoc`               varchar(10) default ‘0’,    /*文件大小(格式化的)*/

  `f_pos`                   bigint(19) default ‘0’,     /*续传位置*/

  `f_lenSvr`           bigint(19) default ‘0’,     /*已上传大小*/

  `f_perSvr`           varchar(7) default ‘0%’,    /*已上传百分比*/

  `f_complete`              tinyint(1) default ‘0’,     /*是否已上传完毕*/

  `f_time`                  timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

  `f_deleted`               tinyint(1) default ‘0’,

  `f_scan`                  tinyint(1) default ‘0’,

  PRIMARY KEY  (`f_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

该项目核心就是文件分块上传。前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题。

* 如何分片;

* 如何合成一个文件;

* 中断了从哪个分片开始。

如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子。但是因为时间的关系还有工作的关系,我只能罢休了。最后我选择了百度的WebUploader来实现前端所需。

如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的。刚开始的时候,我是采用了前端生成了唯一uuid来做文件的标志,在每个分片请求上带上。不过后来在做秒传的时候我放弃了,采用了Md5来维护分块和文件关系。

在服务端合并文件,和记录分块的问题,在这方面其实行业已经给了很好的解决方案了。参考迅雷,你会发现,每次下载中的时候,都会有两个文件,一个文件主体,另外一个就是文件临时文件,临时文件存储着每个分块对应字节位的状态。

这些都是需要前后端密切联系才能做好,前端需要根据固定大小对文件进行分片,并且请求中要带上分片序号和大小。前端发送请求顺利到达后台后,服务器只需要按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件即可。

为了便于开发,我 将服务端的业务逻辑进行了如下划分,分成初始化,块处理,文件上传完毕等。

服务端的业务逻辑模块如下

 

 

功能分析:

文件夹生成模块

 

文件夹上传完毕后由服务端进行扫描代码如下

public class fd_scan

{

    DbHelper db;

    Connection con;

    PreparedStatement cmd_add_f = null;

    PreparedStatement cmd_add_fd = null;

    public FileInf root = null;//根节点

   

    public fd_scan()

    {

        this.db = new DbHelper();

        this.con = this.db.GetCon();       

    }

   

    public void makeCmdF()

    {

        StringBuilder sb = new StringBuilder();

        sb.append(“insert into up6_files (“);

        sb.append(” f_id”);//1

        sb.append(“,f_pid”);//2

        sb.append(“,f_pidRoot”);//3

        sb.append(“,f_fdTask”);//4

        sb.append(“,f_fdChild”);//5

        sb.append(“,f_uid”);//6

        sb.append(“,f_nameLoc”);//7

        sb.append(“,f_nameSvr”);//8

        sb.append(“,f_pathLoc”);//9

        sb.append(“,f_pathSvr”);//10

        sb.append(“,f_pathRel”);//11

        sb.append(“,f_md5”);//12

        sb.append(“,f_lenLoc”);//13

        sb.append(“,f_sizeLoc”);//14

        sb.append(“,f_lenSvr”);//15

        sb.append(“,f_perSvr”);//16

        sb.append(“,f_complete”);//17

       

        sb.append(“) values(“);

       

        sb.append(” ?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“)”);

 

        try {

            this.cmd_add_f = this.con.prepareStatement(sb.toString());

            this.cmd_add_f.setString(1, “”);//id

            this.cmd_add_f.setString(2, “”);//pid

            this.cmd_add_f.setString(3, “”);//pidRoot

            this.cmd_add_f.setBoolean(4, true);//fdTask

            this.cmd_add_f.setBoolean(5, false);//f_fdChild

            this.cmd_add_f.setInt(6, 0);//f_uid

            this.cmd_add_f.setString(7, “”);//f_nameLoc

            this.cmd_add_f.setString(8, “”);//f_nameSvr

            this.cmd_add_f.setString(9, “”);//f_pathLoc

            this.cmd_add_f.setString(10, “”);//f_pathSvr

            this.cmd_add_f.setString(11, “”);//f_pathRel

            this.cmd_add_f.setString(12, “”);//f_md5

            this.cmd_add_f.setLong(13, 0);//f_lenLoc

            this.cmd_add_f.setString(14, “”);//f_sizeLoc

            this.cmd_add_f.setLong(15, 0);//f_lenSvr            

            this.cmd_add_f.setString(16, “”);//f_perSvr

            this.cmd_add_f.setBoolean(17, true);//f_complete

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    public void makeCmdFD()

    {

        StringBuilder sb = new StringBuilder();

        sb.append(“insert into up6_folders (“);

        sb.append(” f_id”);//1

        sb.append(“,f_pid”);//2

        sb.append(“,f_pidRoot”);//3

        sb.append(“,f_nameLoc”);//4

        sb.append(“,f_uid”);//5

        sb.append(“,f_pathLoc”);//6

        sb.append(“,f_pathSvr”);//7

        sb.append(“,f_pathRel”);//8

        sb.append(“,f_complete”);//9

        sb.append(“) values(“);//

        sb.append(” ?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“,?”);

        sb.append(“)”);

 

        try {

            this.cmd_add_fd = this.con.prepareStatement(sb.toString());

            this.cmd_add_fd.setString(1, “”);//id

            this.cmd_add_fd.setString(2, “”);//pid

            this.cmd_add_fd.setString(3, “”);//pidRoot

            this.cmd_add_fd.setString(4, “”);//name

            this.cmd_add_fd.setInt(5, 0);//f_uid

            this.cmd_add_fd.setString(6, “”);//pathLoc

            this.cmd_add_fd.setString(7, “”);//pathSvr

            this.cmd_add_fd.setString(8, “”);//pathRel

            this.cmd_add_fd.setBoolean(9, true);//complete

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    protected void GetAllFiles(FileInf inf,String root)

    {

        File dir = new File(inf.pathSvr);

        File [] allFile = dir.listFiles();

        for(int i = 0; i < allFile.length; i++)

        {

            if(allFile[i].isDirectory())

            {

                FileInf fd = new FileInf();

                String uuid = UUID.randomUUID().toString();

                uuid = uuid.replace(“-“, “”);

                fd.id = uuid;

                fd.pid = inf.id;

                fd.pidRoot = this.root.id;

                fd.nameSvr = allFile[i].getName();

                fd.nameLoc = fd.nameSvr;

                fd.pathSvr = allFile[i].getPath();

                fd.pathSvr = fd.pathSvr.replace(“\\”, “/”);

                fd.pathRel = fd.pathSvr.substring(root.length() + 1);

                fd.perSvr = “100%”;

                fd.complete = true;

                this.save_folder(fd);

               

                this.GetAllFiles(fd, root);

            }

            else

            {

                FileInf fl = new FileInf();

                String uuid = UUID.randomUUID().toString();

                uuid = uuid.replace(“-“, “”);

                fl.id = uuid;

                fl.pid = inf.id;

                fl.pidRoot = this.root.id;

                fl.nameSvr = allFile[i].getName();

                fl.nameLoc = fl.nameSvr;

                fl.pathSvr = allFile[i].getPath();

                fl.pathSvr = fl.pathSvr.replace(“\\”, “/”);

                fl.pathRel = fl.pathSvr.substring(root.length() + 1);

                fl.lenSvr = allFile[i].length();

                fl.lenLoc = fl.lenSvr;

                fl.perSvr = “100%”;

                fl.complete = true;

                this.save_file(fl);

            }

        }

    }

   

    protected void save_file(FileInf f)

    {      

        try {

            this.cmd_add_f.setString(1, f.id);//id

            this.cmd_add_f.setString(2, f.pid);//pid

            this.cmd_add_f.setString(3, f.pidRoot);//pidRoot

            this.cmd_add_f.setBoolean(4, f.fdTask);//fdTask

            this.cmd_add_f.setBoolean(5, true);//f_fdChild

            this.cmd_add_f.setInt(6, f.uid);//f_uid

            this.cmd_add_f.setString(7, f.nameLoc);//f_nameLoc

            this.cmd_add_f.setString(8, f.nameSvr);//f_nameSvr

            this.cmd_add_f.setString(9, f.pathLoc);//f_pathLoc

            this.cmd_add_f.setString(10, f.pathSvr);//f_pathSvr

            this.cmd_add_f.setString(11, f.pathRel);//f_pathRel

            this.cmd_add_f.setString(12, f.md5);//f_md5

            this.cmd_add_f.setLong(13, f.lenLoc);//f_lenLoc

            this.cmd_add_f.setString(14, f.sizeLoc);//f_sizeLoc

            this.cmd_add_f.setLong(15, f.lenSvr);//f_lenSvr        

            this.cmd_add_f.setString(16, f.perSvr);//f_perSvr

            this.cmd_add_f.setBoolean(17, f.complete);//f_complete

            this.cmd_add_f.executeUpdate();

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }//

    }

   

    protected void save_folder(FileInf f)

    {

        try {

            this.cmd_add_fd.setString(1, f.id);//id

            this.cmd_add_fd.setString(2, f.pid);//pid

            this.cmd_add_fd.setString(3, f.pidRoot);//pidRoot

            this.cmd_add_fd.setString(4, f.nameSvr);//name

            this.cmd_add_fd.setInt(5, f.uid);//f_uid

            this.cmd_add_fd.setString(6, f.pathLoc);//pathLoc

            this.cmd_add_fd.setString(7, f.pathSvr);//pathSvr

            this.cmd_add_fd.setString(8, f.pathRel);//pathRel

            this.cmd_add_fd.setBoolean(9, f.complete);//complete

            this.cmd_add_fd.executeUpdate();

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

    public void scan(FileInf inf, String root) throws IOException, SQLException

    {

        this.makeCmdF();

        this.makeCmdFD();

        this.GetAllFiles(inf, root);

        this.cmd_add_f.close();

        this.cmd_add_fd.close();

        this.con.close();

    }

}

 

分块上传,分块处理逻辑应该是最简单的逻辑了,up6已经将文件进行了分块,并且对每个分块数据进行了标识,这些标识包括文件块的索引,大小,偏移,文件MD5,文件块MD5(需要开启)等信息,服务端在接收这些信息后便可以非常方便的进行处理了。比如将块数据保存到分布式存储系统中

分块上传可以说是我们整个项目的基础,像断点续传、暂停这些都是需要用到分块。

分块这块相对来说比较简单。前端是采用了webuploader,分块等基础功能已经封装起来,使用方便。

借助webUpload提供给我们的文件API,前端就显得异常简单。

前台HTML模板

this.GetHtmlFiles = function()

{

     var acx = “”;

     acx += ‘<div class=”file-item” id=”tmpFile” name=”fileItem”>\

                <div class=”img-box”><img name=”file” src=”js/file.png”/></div>\

                   <div class=”area-l”>\

                       <div class=”file-head”>\

                            <div name=”fileName” class=”name”>HttpUploader程序开发.pdf</div>\

                            <div name=”percent” class=”percent”>(35%)</div>\

                            <div name=”fileSize” class=”size” child=”1″>1000.23MB</div>\

                    </div>\

                       <div class=”process-border”><div name=”process” class=”process”></div></div>\

                       <div name=”msg” class=”msg top-space”>15.3MB 20KB/S 10:02:00</div>\

                   </div>\

                   <div class=”area-r”>\

                    <span class=”btn-box” name=”cancel” title=”取消”><img name=”stop” src=”js/stop.png”/><div>取消</div></span>\

                    <span class=”btn-box hide” name=”post” title=”继续”><img name=”post” src=”js/post.png”/><div>继续</div></span>\

                       <span class=”btn-box hide” name=”stop” title=”停止”><img name=”stop” src=”js/stop.png”/><div>停止</div></span>\

                       <span class=”btn-box hide” name=”del” title=”删除”><img name=”del” src=”js/del.png”/><div>删除</div></span>\

                   </div>’;

     acx += ‘</div>’;

     acx += ‘<div class=”file-item” name=”folderItem”>\

                   <div class=”img-box”><img name=”folder” src=”js/folder.png”/></div>\

                   <div class=”area-l”>\

                       <div class=”file-head”>\

                            <div name=”fileName” class=”name”>HttpUploader程序开发.pdf</div>\

                            <div name=”percent” class=”percent”>(35%)</div>\

                            <div name=”fileSize” class=”size” child=”1″>1000.23MB</div>\

                    </div>\

                       <div class=”process-border top-space”><div name=”process” class=”process”></div></div>\

                       <div name=”msg” class=”msg top-space”>15.3MB 20KB/S 10:02:00</div>\

                   </div>\

                   <div class=”area-r”>\

                    <span class=”btn-box” name=”cancel” title=”取消”><img name=”stop” src=”js/stop.png”/><div>取消</div></span>\

                    <span class=”btn-box hide” name=”post” title=”继续”><img name=”post” src=”js/post.png”/><div>继续</div></span>\

                       <span class=”btn-box hide” name=”stop” title=”停止”><img name=”stop” src=”js/stop.png”/><div>停止</div></span>\

                       <span class=”btn-box hide” name=”del” title=”删除”><img name=”del” src=”js/del.png”/><div>删除</div></span>\

                   </div>’;

     acx += ‘</div>’;

     acx += ‘<div class=”files-panel” name=”post_panel”>\

                   <div name=”post_head” class=”toolbar”>\

                       <span class=”btn” name=”btnAddFiles”>选择多个文件</span>\

                       <span class=”btn” name=”btnAddFolder”>选择文件夹</span>\

                       <span class=”btn” name=”btnPasteFile”>粘贴文件和目录</span>\

                       <span class=”btn” name=”btnSetup”>安装控件</span>\

                   </div>\

                   <div class=”content” name=”post_content”>\

                       <div name=”post_body” class=”file-post-view”></div>\

                   </div>\

                   <div class=”footer” name=”post_footer”>\

                       <span class=”btn-footer” name=”btnClear”>清除已完成文件</span>\

                   </div>\

              </div>’;

     return acx;

};

 

分则必合。把大文件分片了,但是分片了就没有原本文件功能,所以我们要把分片合成为原本的文件。我们只需要把分片按原本位置写入到文件中去。因为前面原理那一部我们已经讲到了,我们知道分块大小和分块序号,我就可以知道该分块在文件中的起始位置。所以这里使用RandomAccessFile是明智的,RandomAccessFile能在文件里面前后移动。但是在andomAccessFile的绝大多数功能,已经被JDK1.4的NIO的“内存映射文件(memory-mapped files)”取代了。我在该项目中分别写了使用RandomAccessFile与MappedByteBuffer来合成文件。分别对应的方法是uploadFileRandomAccessFile和uploadFileByMappedByteBuffer。两个方法代码如下。

秒传功能

服务端逻辑

秒传功能,相信大家都体现过了,网盘上传的时候,发现上传的文件秒传了。其实原理稍微有研究过的同学应该知道,其实就是检验文件MD5,记录下上传到系统的文件的MD5,在一个文件上传前先获取文件内容MD5值或者部分取值MD5,然后在匹配系统上的数据。

Breakpoint-http实现秒传原理,客户端选择文件之后,点击上传的时候触发获取文件MD5值,获取MD5后调用系统一个接口(/index/checkFileMd5),查询该MD5是否已经存在(我在该项目中用redis来存储数据,用文件MD5值来作key,value是文件存储的地址。)接口返回检查状态,然后再进行下一步的操作。相信大家看代码就能明白了。

嗯,前端的MD5取值也是用了webuploader自带的功能,这还是个不错的工具。

控件计算完文件MD5后会触发md5_complete事件,并传值md5,开发者只需要处理这个事件即可,

 

断点续传

up6已经自动对断点续传进行了处理,不需要开发都再进行单独的处理。

在f_post.jsp中接收这些参数,并进行处理,开发者只需要关注业务逻辑,不需要关注其它的方面。

 

断点续传,就是在文件上传的过程中发生了中断,人为因素(暂停)或者不可抗力(断网或者网络差)导致了文件上传到一半失败了。然后在环境恢复的时候,重新上传该文件,而不至于是从新开始上传的。

前面也已经讲过,断点续传的功能是基于分块上传来实现的,把一个大文件分成很多个小块,服务端能够把每个上传成功的分块都落地下来,客户端在上传文件开始时调用接口快速验证,条件选择跳过某个分块。

实现原理,就是在每个文件上传前,就获取到文件MD5取值,在上传文件前调用接口(/index/checkFileMd5,没错也是秒传的检验接口)如果获取的文件状态是未完成,则返回所有的还没上传的分块的编号,然后前端进行条件筛算出哪些没上传的分块,然后进行上传。

当接收到文件块后就可以直接写入到服务器的文件中

这是文件夹上传完后的效果

 

这是文件夹上传完后在服务端的存储结构

 

参考文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

]]>
vue解决大文件断点续传 http://blog.ncmem.com/wordpress/2019/12/16/vue%e8%a7%a3%e5%86%b3%e5%a4%a7%e6%96%87%e4%bb%b6%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/ Mon, 16 Dec 2019 05:39:20 +0000 http://blog.ncmem.com/wordpress/?p=1604 继续阅读 vue解决大文件断点续传]]> 相关资料:解决方案,白皮书,产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

        

产品交流群:泽优Web大文件上传控件

视频教程:https://www.bilibili.com/video/BV1jm4y127Ut/?vd_source=d1843c7f8c164416779b5188178bad8c

环境:vue2-cli

示例:https://gitee.com/xproer/up6-vue-cli

 

1.下载示例

 

将up6组件复制到项目中

示例中已经包含此目录

 

1.引入up6组件

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

3.处理事件

 

启动测试

 

启动成功

 

访问测试页面

 

效果

 

数据库

 

下载产品源代码-泽优全平台开源大文件上传控件(up6)

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>
webuploader解决大文件断点续传 http://blog.ncmem.com/wordpress/2019/12/16/webuploader%e8%a7%a3%e5%86%b3%e5%a4%a7%e6%96%87%e4%bb%b6%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/ Mon, 16 Dec 2019 03:26:55 +0000 http://blog.ncmem.com/wordpress/?p=1602 继续阅读 webuploader解决大文件断点续传]]> 相关资料:产品首页,白皮书,控件包,白皮书(图文版),产品介绍,产品比较,开发文档,成功案例,基础组件,示例下载,控件包,控件升级,在线演示,在线文档,并发能力,上传速度,下载速度,Windows控件安装,macOS控件安装,Linux-deb控件安装,Linux-rpm控件安装,安装引导,控件布署,控件升级,IE9加载控件,IE8加载控件,

标杆案例:中国港湾中国中车中国石油中国石化,长江电力中信证券上海通用一汽大众,沈阳自动化研究所,

解决方案:党政央企国防军工房地产档案管理教育医疗工程管理企业文件传输解决方案

示例下载:asp.net-vs2013,asp.net-vs2010,jsp-eclipse,jsp-springboot,jsp-myeclipse,php,vue-cil,WinForm(C#),C++(WTL)

教程:WinForm(C#)测试,WTL(C++)测试,在vue.js中使用,在vue-cli中使用,eclipse导入up6

视频教程:windows控件安装,mac控件安装,linux-deb控件包安装,linux-rpm控件包安装,php7测试,php5测试,vue-cli-测试,asp.net-IIS Express测试,asp.net-IIS测试,asp.net-阿里云(oss)测试,asp.net-华为云(obs)测试,jsp-springboot测试,ActiveX(x86)源码编译,ActiveX(x64)源码编译,Windows(npapi)源码编译,macOS源码编译,Linux(x86_64)源码编译,Linux(arm)源码编译,Linux(mips-uos)源码编译,Linux(mips-kylin-涉密环境)源码编译,sm4加密传输,压缩传输,jsp-eclipse-sm4加密存储,jsp-springboot-sm4加密存储,asp.net-sm4加密存储

ASP.NET教程:asp.net,IIS Express,IIS,IIS-Https,Oracle,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-eclipse教程:测试教程,oracle,mysql,SQL Server,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs),

jsp-springboot教程:测试教程,minio,fastdfs,阿里云对象存储(oss),华为云对象存储(obs)

jsp-myeclipse教程:mysql,oracle,SQL Server,fastdfs

php教程:测试教程,minio,fastdfs,阿里云对象存储(oss),

二次开发:组件引用,自定义事件,自定义业务字段,自定义文件保存路径,授权码,加密存储,加密传输,使用Minio存储,使用FastDFS存储,使用达梦数据库,数据表字段设计,监控fd_create流程,监控f_create流程,监控f_list.jsp流程

相关问题:WebSocket连接失败,md5计算完毕后卡住,域名未授权,网站安全系统拦截,

联系我们:QQ:1269085759(技术),QQ:3040217208(售后),QQ:1085617561(商务),微信:13235643658,邮箱:1269085759@qq.com,1085617561@qq.com,qwl@ncmem.com,

       

产品交流群:泽优Web大文件上传控件


视频教程:
https://www.ixigua.com/7226245960341389859

 

1.下载示例

https://gitee.com/xproer/up6-vue-cli

 

 

up6组件复制到项目中

示例中已经包含此目录

 

 

1.引入up6组件

 

 

2.配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表

参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

 

 

3.处理事件

 

 

启动测试

 

 

启动成功

 

 

效果

 

 

数据库

 

 

大文件上传控件(up6

个人版:http://www.ncmem.com/webapp/up6/purchase.aspx

政企版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=ent

年费版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=year

OEM版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=oem

源码版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=code

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

 

大文件上传下载控件(up6-down2

政企版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=ent

年费版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=year

OEM版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=oem

源码版:http://www.ncmem.com/webapp/up6/purchase.aspx?type=code

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

免费下载源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc

免费下载授权器:https://drive.weixin.qq.com/s?k=ACoAYgezAAw0P06owX

]]>