机器人论坛
直播中

李桢

8年用户 146经验值
私信 关注
[问答]

请问500M的NET大文件怎么上传?

NET大文件上传解决方案

回帖(4)

杨敏

2020-11-4 16:53:04
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。
首先我们需要了解的是上传文件三要素:
1.表单提交方式:post (get方式提交有大小限制,post没有)
2.表单的enctype属性:必须设置为multipart/form-data.
3.表单必须有文件上传项:file,且文件项需要给定name值
上传文件夹需要增加一个属性webkitdirectory,像这样:
不过webkitdirectory属性有个问题,只能支持高版本的chrome,不能支持低版本的IE,如ie6,ie7,ie8,不能做到全浏览器适配,运行环境比较单一。
js中可以判断文件夹中文件数量及文件夹大小是否符合要求,不符合要求不能向后台提交:
举报

侯晓萃

2020-11-4 16:53:39
前台HTML模板
this.GetHtmlFiles = function()
{
     var acx = "";
     acx += '/
               
/

                  
/
                       
/
                           
HttpUploader程序开发.pdf
/

                           
(35%)
/

                           
1000.23MB
/

                    
/
                       
/

                       
15.3MB 20KB/S 10:02:00
/

                  
/
                  
/
                    
取消
/

                    
继续
/

                       
停止
/

                       
删除
/

                  
';
     acx += '
';
     //文件夹模板
     acx += '/
                  
/

                  
/
                       
/
                           
HttpUploader程序开发.pdf
/

                           
(35%)
/

                           
1000.23MB
/

                    
/
                       
/

                       
15.3MB 20KB/S 10:02:00
/

                  
/
                  
/
                    
取消
/

                    
继续
/

                       
停止
/

                       
删除
/

                  
';
     acx += '
';
     //上传列表
     acx += '/
                  
/
                       选择多个文件/
                       选择文件夹/
                       粘贴文件和目录/
                       安装控件/
                  
/
                   /
                       
/

                  
/
                   /
                       清除已完成文件/
                  
/
              
';
     return acx;
};
选择文件,选择文件夹,粘贴文件和文件夹的逻辑
this.open_files = function (json)
{
     for (var i = 0, l = json.files.length; i < l; ++i)
    {
         this.addFileLoc(json.files);
     }
     setTimeout(function () { _this.PostFirst(); },500);
};
this.open_folders = function (json)
{
    for (var i = 0, l = json.folders.length; i < l; ++i) {
        this.addFolderLoc(json.folders);
    }
     setTimeout(function () { _this.PostFirst(); }, 500);
};
this.paste_files = function (json)
{
     for (var i = 0, l = json.files.length; i < l; ++i)
     {
         this.addFileLoc(json.files);
     }
};
后台在接收文件夹时不同之处在需要用MultipartHttpServletRequest
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);
     }
}
';
     //文件夹模板
     acx += '/
                  
/

                  
/
                       
/
                           
HttpUploader程序开发.pdf
/

                           
(35%)
/

                           
1000.23MB
/

                    
/
                       
/

                       
15.3MB 20KB/S 10:02:00
/

                  
/
                  
/
                    
取消
/

                    
继续
/

                       
停止
/

                       
删除
/

                  
';
     acx += '';
     //上传列表
     acx += '/
                  
/
                       选择多个文件/
                       选择文件夹/
                       粘贴文件和目录/
                       安装控件/
                  
/
                   /
                       
/

                   /
                   /
                       清除已完成文件/
                   /
              ';
     return acx;
};
选择文件,选择文件夹,粘贴文件和文件夹的逻辑
this.open_files = function (json)
{
     for (var i = 0, l = json.files.length; i < l; ++i)
    {
         this.addFileLoc(json.files);
     }
     setTimeout(function () { _this.PostFirst(); },500);
};
this.open_folders = function (json)
{
    for (var i = 0, l = json.folders.length; i < l; ++i) {
        this.addFolderLoc(json.folders);
    }
     setTimeout(function () { _this.PostFirst(); }, 500);
};
this.paste_files = function (json)
{
     for (var i = 0, l = json.files.length; i < l; ++i)
     {
         this.addFileLoc(json.files);
     }
};
后台在接收文件夹时不同之处在需要用MultipartHttpServletRequest
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);
     }
}
举报

刘斯宁

2020-11-4 16:54:05
server端的包和类


文件块处页面,验证代码部分
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);

生成文件名称的逻辑
public String genFile(int uid, String md5,String nameLoc) throws IOException
{
     SimpleDateFormat fmtDD = new SimpleDateFormat("dd");
     SimpleDateFormat fmtMM = new SimpleDateFormat("MM");
     SimpleDateFormat fmtYY = new SimpleDateFormat("yyyy");
   
     Date date = new Date();
     String strDD = fmtDD.format(date);
     String strMM = fmtMM.format(date);
     String strYY = fmtYY.format(date);
   
     String path = this.getRoot() + "/";
     path = path.concat(strYY);
     path = path.concat("/");
     path = path.concat(strMM);
     path = path.concat("/");
     path = path.concat(strDD);
     path = path.concat("/");
     path = path.concat(md5);
     path = path.concat(".");
     path = path.concat(PathTool.getExtention(nameLoc));
        
   
     File fl = new File(path);
   
     return fl.getCanonicalPath();//
}

以下是service层做的处理:
整体模块划分如下:

其中数据类实体逻辑处理如下
public class FileInf {

     public FileInf(){}
     public String ;
     public String p;
    public String pidRoot="";   
     /**  * 表示当前项是否是一个文件夹项。    */
     public boolean fdTask=false;        
     //   /// 是否是文件夹中的子文件  ///
     public boolean fdChild=false;
     /**  * 用户ID。与第三方系统整合使用。    */
     public int uid=0;
     /**  * 文件在本地电脑中的名称   */
     public String nameLoc="";
     /**  * 文件在服务器中的名称。   */
     public String nameSvr="";
     /**  * 文件在本地电脑中的完整路径。示例:D:/Soft/QQ2012.exe */
     public String pathLoc="";  
     /**  * 文件在服务器中的完整路径。示例:F://ftp//uer//md5.exe     */
     public String pathSvr="";
     /**  * 文件在服务器中的相对路径。示例:/www/web/upload/md5.exe   */
     public String pathRel="";
     /**  * 文件MD5    */
     public String md5="";
     /**  * 数字化的文件长度。以字节为单位,示例:120125    */
     public long lenLoc=0;
     /**  * 格式化的文件尺寸。示例:10.03MB   */
     public String sizeLoc="";
     /**  * 文件续传位置。  */
     public long offset=0;
     /**  * 已上传大小。以字节为单位 */
     public long lenSvr=0;
     /**  * 已上传百分比。示例:10%  */
     public String perSvr="0%";
     public boolean complete=false;
     public Date PostedTime = new Date();
     public boolean deleted=false;
     /**  * 是否已经扫描完毕,提供给大型文件夹使用,大型文件夹上传完毕后开始扫描。  */
     public boolean scaned=false;
}
后台数据库中的逻辑基本上都用到了上面的实体类
文件数据表操作类如下
加载所有未完成的文件列表
public String GetAllUnComplete(int f_uid)
{
     StringBuilder *** = new StringBuilder();
     ***.append("select ");
     ***.append(" f_id");
     ***.append(",f_fdTask");   
     ***.append(",f_nameLoc");
     ***.append(",f_pathLoc");
     ***.append(",f_md5");
     ***.append(",f_lenLoc");
     ***.append(",f_sizeLoc");
     ***.append(",f_pos");
     ***.append(",f_lenSvr");
     ***.append(",f_perSvr");
     ***.append(",f_complete");
     ***.append(",f_pathSvr");//fix(2015-03-16):修复无法续传文件的问题。
     ***.append(" from up6_files ");//change(2015-03-18):联合查询文件夹数据
     ***.append(" where f_uid=? and f_deleted=0 and f_fdChild=0 and f_complete=0 and f_scan=0");//fix(2015-03-18):只加载未完成列表

     ArrayList files = new ArrayList();
     DbHelper db = new DbHelper();
     PreparedStatement cmd = db.GetCommand(***.toString());
     try {
         cmd.setInt(1, f_uid);
         ResultSet r = db.ExecuteDataSet(cmd);
         while(r.next())
         {
              FileInf f          = new FileInf();
              f.uid              = f_uid;
              f.id               = r.getString(1);
              f.fdTask      = r.getBoolean(2);              
              f.nameLoc          = r.getString(3);
              f.pathLoc          = r.getString(4);
              f.md5              = r.getString(5);
              f.lenLoc      = r.getLong(6);
              f.sizeLoc          = r.getString(7);
              f.offset      = r.getLong(8);
              f.lenSvr      = r.getLong(9);
              f.perSvr      = r.getString(10);
              f.complete         = r.getBoolean(11);
              f.pathSvr     = r.getString(12);//fix(2015-03-19):修复无法续传文件的问题。
              files.add(f);
            
         }
         r.close();
         cmd.getConnection().close();
         cmd.close();
     } catch (SQLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
     }
   
     if(files.size() < 1) return null;
   
     Gson g = new Gson();
    return g.toJson( files);//bug:arrFiles为空时,此行代码有异常
}
举报

张变英

2020-11-4 16:54:22
实现后的整体效果如下

文件夹上传完后的效果

服务器保存的文件夹数据,而且层级结构与本地客户端是一致的。这在OA系统中,或者网盘系统中使用时是非常有用的
举报

更多回帖

相关问答

net 文件
发帖
登录/注册
×
20
完善资料,
赚取积分