基于孤傲苍狼的上传下载总结出的java工具类

import com.mysql.jdbc.Buffer;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Create by jlimingyang
 * Email: wdful165177@gmail.com
 * Date: 2017/5/10
 * <p>
 * 上传工具类
 * 需要commons-io-2.5.jar
 * commons-fileupload-1.3.2.jar
 */
public class UploadAndDownload {
    /**
     * @param filename 文件的原始名称
     * @return uuid+"_"+文件的原始名称
     * @Method: makeFileName
     * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称
     * @Anthor:wdful
     */

    private static String makeFileName(String filename) {  //2.jpg
        //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
        return UUID.randomUUID().toString() + "_" + filename;
    }

    /**
     * 为防止一个目录下面出现太多文件,要使用hash算法打散存储
     *
     * @param filename 文件名,要根据文件名生成存储目录
     * @param savePath 文件存储路径
     * @return 新的存储目录
     * @Method: makePath
     * @Description:
     * @Anthor:wdful
     */
    private static String makePath(String filename, String savePath) {
        //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
        int hashcode = filename.hashCode();
        int dir1 = hashcode & 0xf;  //0--15
        int dir2 = (hashcode & 0xf0) >> 4;  //0-15
        //构造新的保存目录
        String dir = savePath + "//" + dir1 + "//" + dir2;  //upload\2\3  upload\3\5
        //File既可以代表文件也可以代表目录
        File file = new File(dir);
        //如果目录不存在
        if (!file.exists()) {
            //创建目录
            file.mkdirs();
        }
        return dir;
    }

    /**
     * Create by Wdful
     * Author:Wdful
     * Email: wdful165177@gmail.com
     * 通过文件名找目录
     */
    public String findFileSavePathByFileName(String filename, String saveRootPath) {
        int hashcode = filename.hashCode();
        int dir1 = hashcode & 0xf;  //0--15
        int dir2 = (hashcode & 0xf0) >> 4;  //0-15
        String dir = saveRootPath + "//" + dir1 + "//" + dir2;  //upload\2\3  upload\3\5
        File file = new File(dir);
        return dir;
    }

    //上传
    public Map<String, Object> uploadFile(String savePath, String temPath, String Ext_Name, HttpServletRequest request) {
        //Ext_Name : 文件扩展名限制
        //        String Ext_Name = "gif,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";
        //        String savePath = this..getRealPath("/WEB-INF/upload");
        //String temPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        int setSizeThreshold = 1024 * 10; //设置缓冲区大小 默认为10kb
        int setFileSizeMax = 1024 * 1024 * 10;//设置单个文件的最大上传大小
        int setSizeMax = 1024 * 1024 * 1024;//设置所有文件的最大上传大小
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", false);  //上传状态
        map.put("msg", "上传失败!"); //上传返回信息
        // 定义允许上传的文件扩展名
        //上传路径定位到web-inf下  可以保证不被外界访问
        File file = new File(savePath);
        //判断上传文件的保存目录是否存在
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }
        //生成临时目录
        File tempfile = new File(temPath);
        if (!tempfile.exists() && !tempfile.isDirectory()) {
            tempfile.mkdir();
        }
        //消息提示
//        String msg = "";
        try {
            //使用Apache文件上传组件处理文件上传
            // 创建一个DiskFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
            factory.setSizeThreshold(setSizeThreshold);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
            //设置上传时生成的临时文件的保存目录
            factory.setRepository(tempfile);
            //创建一个文件上传解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            //监听文件上传进度
            upload.setProgressListener(new ProgressListener() {
                @Override
                public void update(long l, long l1, int i) {
                    System.out.println("文件大小为:" + l1 + ",当前已处理:" + l);
                    /**
                     * 文件大小为:22480,当前已处理:4096
                     */
                }
            });
            //解决上传文件名的中文乱码
            upload.setHeaderEncoding("UTF-8");
            //判断提交的数据是不是上传表单的数据
            if (!upload.isMultipartContent(request)) {
                return map;
            }
            //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
            upload.setFileSizeMax(setFileSizeMax);
            //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为1g
            upload.setSizeMax(setSizeMax);
            //使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
            List<FileItem> list = upload.parseRequest(request);
            for (FileItem item : list) {
                //获取普通输入和文件的数据
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    String value = item.getString("utf-8");
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + ":" + value);
                } else {
                    String fileName = item.getName();
                    if (fileName == null || fileName.trim().equals(" ")) {
                        continue;
                    }
                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                    //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                    fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                    String fileExtname = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
                    System.out.println("fileExtname:" + fileExtname);
                    //判断支持上传的文件格式
                    if (!Ext_Name.contains(fileExtname)) {
                        map.put("msg", "文件格式不正确!不支持的:" + fileExtname);
                        continue;
                    }
                    //获取文件输入流
                    BufferedInputStream bin = new BufferedInputStream(item.getInputStream());
                    savePath = this.makePath(fileName, savePath);
                    fileName = this.makeFileName(fileName);
                    System.out.println(savePath + "----" + fileName);
                    //文件输出流
                    BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(savePath + "//" + fileName));
                    //缓冲区
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    int len = 0;
                    while ((len = bin.read(buffer)) != -1) {
                        bout.write(buffer, 0, len);
                    }
                    bout.close();
                    bin.close();
                    //删除处理文件上传时生成的临时文件
                    item.delete();
                    map.put("msg", "文件上传成功!");
                    return map;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    //下载
    public Map<String, Object> downloadFile(String fileName, String fileSaveRootPath, HttpServletResponse response) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", false);
        map.put("msg", "下载失败!");
        try {
            fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");
            //根据文件名查找目录
            String path = this.findFileSavePathByFileName(fileName, fileSaveRootPath);
            //获取要下载的文件
            File file = new File(path + "\\" + fileName);
            if (!file.exists()) {
                map.put("msg", "文件不存在!");
                return map;
            }
            //处理文件名
            String realName = fileName.substring(fileName.indexOf("_") + 1);
            //设置响应头
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realName, "UTF-8"));
            //读取要下载的文件
            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(path + "\\" + fileName));
            //输出流
            BufferedOutputStream bout = new BufferedOutputStream(response.getOutputStream());
            byte[] buffer = new byte[1024 * 1024 * 2];
            int len=0;
            while((len=bin.read(buffer)) != -1){
                bout.write(buffer,0,len);
            }
            bout.close();
            bin.close();
            map.put("status",true);
            map.put("msg","下载成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * @param file 即代表一个文件,也代表一个文件目录
     * @param map  存储文件名的Map集合
     * @Method: listfile
     * @Description: 递归遍历指定目录下的所有文件
     * @Anthor:wdful
     */
    public void listfile(File file, Map<String, String> map) {
        //如果file代表的不是一个文件,而是一个目录
        if (!file.isFile()) {
            //列出该目录下的所有文件和目录
            File files[] = file.listFiles();
            //遍历files[]数组
            for (File f : files) {
                //递归
                listfile(f, map);
            }
        } else {
            /**
             * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
             file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi
             那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分
             */
            String realName = file.getName().substring(file.getName().indexOf("_") + 1);
            //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
            map.put(file.getName(), realName);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳十三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值