zoukankan      html  css  js  c++  java
  • 文件上传与下载

    一、文件上传表单(common-fileupload-xxx.jar包和common-io-xxx.jar包)
    一】分析:
    1)上传文件的本质是一个文本复制的过程
    2)技术层面,在Java中一定会用到IO操作,主要以字节流的方式
    3)传统方式下,对于上传文件字段不同的浏览器有着不同的解析方式。(例如:IE6:D:a.jpg 、非IE6:a.jpg)
    4)可以将form以MIME协议的方式将文件上传到服务端,服务端以二进制流的方式读写.

    二】web端:在web页面中添加上传输入项 ----使用<input type="file">标签
    1)必须要设置name属性,否则浏览器将不会发送上传文件数据
    2)必须把form的enctype属性值设置为multipart/form-data.
    (此时会将文件数据分块后、附带在http请求的消息体中,并使用MIMB协议对上传的文件进行描述,一边接收方对上传的数据进行解析和处理。)
    3)(需使用common-fileupload-xxx.jar包和common-io-xxx.jar包)
    三】service端:
    步骤:
    1)创建一个上传文件工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    2)设置内存中缓存区的大小
    factory.setSizeThreshold(100*1024);//设置内存缓冲区大小为100K
    3)设置上传文件使用的临时目录
    factory.setRepository(new File(tempPath));
    4)创建上传文件对象【核心对象】
    ServletFileUpload upload = new ServletFileUpload(factory);
    5)判断文件是否以MIME协议上传的,如果没有使用,则抛出异常

    Boolean flag = upload.isMultipartContent(request);
    if (!flag)
    throw new FileUploadException();
    

      


    API:
    1)DiskFileItemFactory常用方法:
    a)构造函数
    public DiskFileItemFactory(int sizeThreshold, File repository);
    b)设置内存缓冲区的大小:默认为10K
    public void setSizeThreshold(int sizeThreshold);
    c)设置临时文件目录:默认为java.io.tmpdir
    public void setRepository(java.io.File repository);
    2)ServletFileUpload类:
    a)判断上传文件是否使用MIME协议.(加了multipart/form-data的表单)
    public boolean isMultipartContent(request);//是,返回true;否,返回false.
    b)解析出request中所有的文件形成一个List集合:FileItem表示上传表单中的表单项内容.
    List<FileItem> parseRequest(HttpServletRequest request);
    c)设置上传的文件名称的编码
    setHeaderEncoding(String encoding);//encoding设置为UTF-8可以解决上传文件的名称的中文乱码问题
    3)FileItem类(代表普通字段和上传字段两类)
    a)是否为表单的普通字段:是,true;否,false.
    boolean isFormFiled();
    b)得到普通字段元素的属性名
    String getFiledName();
    c)得到普通字段元素的值
    String getString(String endcoding); //encoding设置为UTF-8可以解决普通字段的中文乱码问题
    d)得到上传文件的名称
    String getName();

    二、上传文件详情
    一】中文乱码的问题
    1)普通字段的中文乱码问题:
    fileItem.getString("UTF-8");即可.
    2)上传字段的中文乱码问题:
    void setHeaderEncoding("UTF-8");
    二】临时文件的删除问题
    a)通过 FileItem类的delete()方法即可删除
    b)但删除必须要在关闭IO流之后,否则删除不成功
    三】在同一个目录下上传相同文件名的问题:
    a)只需要在文件名的前面拼接一个UUID码作为唯一的标识符即可
    四】单个目录下文件过多的问题
    可以通过算法解决,代码如下:
    code:

    private static DBUploadFile initDBUploadFile(FileItem item,HttpServletRequest request, String savePath) { 
    String realName = getRealName(item);
    String uuidName = getUUIDName(realName);
    // 得到实际存储目录
    String upLoadPath = request.getServletContext().getRealPath(
    "\WEB-INF\" + savePath);
    // 创建文件目录,防止一个文件夹下面的文件过多
    String dirsPath = "\";
    Integer fileCode = realName.hashCode();
    Integer tempCode = fileCode;
    while (0 != (tempCode = fileCode & 0XF)) {
    dirsPath += (tempCode + "\");
    fileCode >>>= 4;
    }
    
    // 拼接字符串形成完整文件存储路径
    String upLoadFilePath = upLoadPath + dirsPath + uuidName;
    File upLoadFile = new File(upLoadFilePath);
    // 创建文件夹,防止抛出FileNotFind异常
    File dirFile = upLoadFile.getParentFile();
    if (!dirFile.exists()) {
    dirFile.mkdirs();
    }
    DBUploadFile dbUploadFile = new DBUploadFile();
    dbUploadFile.setFileName(realName);
    dbUploadFile.setFilePath(upLoadFilePath);
    dbUploadFile.setFileItem(item);
    return dbUploadFile;
    }

    五】为安全将上传的文件放入客户端无法直接访问的目录中的问题
    a)将上传的文件,放置到/WEB-INF/upload/目录下
    六】上传文件大小和文件类型的问题:
    通过判断后抛出自定义异常的方式
    code:

    // 如果未上传文件
    long fileSize = item.getSize();
    long maxSize = 200 * 1024;
    if (0 == fileSize)
    throw new NoUploadFileException();
    if (maxSize < fileSize) {
    item.delete();
    throw new UploadFileSizeException(fileSize, maxSize);
    }

    七】上传多个文件的界面问题:
    三】显示下载文件列表(硬盘版)
    a)递归方式查询可供下载的文件,一定要有出口条件
    b)使用Map<UUID文件名,真实文件名>收集可供下载的文件
    c)使用<c:url>和<c:param>对中文名进行URL编码

    四】下载文件
    a)对传过来的中文编码进行URL解码
    b)通过UUID文件名,反向查到该文件所在的真实目录

    五】 文件上传下载与数据库结合
    a)在将上传文件保存的同时,写往数据库表,一个上传文件对应一条记录,确保uuidFileName双方一致

    思考:
    a)上传时,先硬盘,再表?
    b)下载时,先硬盘,再表?
    c)删除时,先硬盘,再表?
    d)是否需要事务支持?

    1 文件上传下载和数据库结合
    1)速度:较小文件的文件存入数据库中,取出速度较快,返之较慢。
    较大文件的存入硬盘中,取出速度相对于数据库较快。
    2)同步:
    数据库表和硬盘必须一致,必须要事务的支持
    在事务的情况下,表操作优先,硬盘其后
    结论:
    1)上传时,先数据库,后硬盘
    2)删除时,先数据库,后硬盘
    原因:数据库异常,可以进行回滚,硬盘内容不能进行回滚

     

     

  • 相关阅读:
    二分 || UOJ 148 跳石头
    等边n边型
    激光样式
    n个数中选k个数和为sum
    引爆炸弹
    光盘行动
    (二分)分蛋糕问题
    总结
    个人测试
    第三次团队作业
  • 原文地址:https://www.cnblogs.com/SkyGood/p/4182053.html
Copyright © 2011-2022 走看看