文件管理总结(文件列表、文件上传/下载)

来源:互联网 发布:stc单片机系统分析 编辑:程序博客网 时间:2024/06/16 13:12

主要实现的功能:

是实现文件列表显示,包括文件夹和文件的列表显示;

文件下载;

文件上传;

(一)文件列表显示

文件列表显示,类似于树形结构的文件夹列表显示。

1、如何实现?

实现方法:

    private static List<FileInfo> getFileInfoList(String path) {        List<FileInfo> list = new LinkedList<>();        File file = new File(path);        if (file.isFile()) {            throw new RuntimeException("不是文件夹");        } else {            File[] lists = file.listFiles();            //循环            for (int i = 0; i < lists.length; i++) {                FileInfo fileInfo = new FileInfo();                File file_i = lists[i];                fileInfo.setName(file_i.getName());                fileInfo.setCapacity(file_i.length() + "");                fileInfo.setUpdateDate(new Date(file_i.lastModified()));                if (file_i.isFile()) {                    fileInfo.setType("file");                } else {                    fileInfo.setType("folder");                }                list.add(fileInfo);            }            return list;        }    }
其中FileInfo中定义了一些属性,主要包括:文件名name、文件大小capacity、修改时间updateDate、文件类型type:

public class FileInfo implements Serializable{    private String id;    private String name;    private String capacity;    private String type;    private Date updateDate;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getCapacity() {        return capacity;    }    public void setCapacity(String capacity) {        this.capacity = capacity;    }    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    public Date getUpdateDate() {        return updateDate;    }    public void setUpdateDate(Date updateDate) {        this.updateDate = updateDate;    }}

参数path从请求中获取,这个path就是文件/文件夹所在的相对路径,在测试类中使用Request.getParameter(path)获得。

实现方法中可以看到,主要的逻辑就是,将目标path创建一个File对象,判断是文件还是文件夹,如果是文件夹,那就对文件夹下的文件/二级文件夹进行遍历,获取相对应的文件/二级文件夹信息,然后以列表的形式返回。


2、如果是POST的请求,后台如何在POST方法中返回json串?

众所周知,Servlet中,POST方法的返回形式是void,所以如何返回给前端json格式的字符串常常让新的同学们产生疑惑,这里提供一种方法:

        response.setCharacterEncoding("UTF-8");        response.setContentType("application/json; charset=utf-8");        String jsonStr = "{\"success\":\"true\"}";        PrintWriter out = null;        try {            out = response.getWriter();            out.write(jsonStr);        } catch (IOException e) {            e.printStackTrace();        } finally {            if (out != null) {                out.close();            }        }

3、测试类(包含跨域问题的后台设置)

public class GetListTest extends HttpServlet {    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //跨域请求解决        response.setHeader("Access-Control-Allow-Origin", "*");        response.setHeader("Access-Control-Allow-Methods", "POST");        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");        response.setContentType("application/json");        response.setCharacterEncoding("utf-8");//获取文件请求路径        String file_path = request.getParameter("file_path");        String path = "***";        if (file_path != null) {            path = "***" + file_path;        }GetListClass getListClass = new GetListClass();        List<FileInfo> aa = GetListClass.getFileInfoList(path);    }}

以上就是文件列表显示的主要部分介绍,源码链接(待补充);


(二)文件上传

1、如何实现?该部分代码注释非常详细,***处与上一节文件列表显示一样,服务器文件根目录,用户不可见。

public class FileUpload extends HttpServlet {    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {                String path = request.getParameter("file_path");        System.out.println(path);        String savePath = "***";        if(path != null){            savePath = "***"+path;        }        //文件上传逻辑        File file = new File(savePath);        System.out.println(savePath);        //判断上传文件的保存目录是否存在        if (!file.exists() && !file.isDirectory()) {            System.out.println(savePath+"目录不存在,需要创建");            //创建目录            file.mkdir();        }        //消息提示        String message = "";        try{            //使用Apache文件上传组件处理文件上传步骤:            //1、创建一个DiskFileItemFactory工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            //2、创建一个文件上传解析器            ServletFileUpload upload = new ServletFileUpload(factory);            //解决上传文件名的中文乱码            upload.setHeaderEncoding("UTF-8");            //3、判断提交上来的数据是否是上传表单的数据            if(!ServletFileUpload.isMultipartContent(request)){                //按照传统方式获取数据                return;            }            //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项            List<FileItem> list = upload.parseRequest(request);            for(FileItem item : list){                //如果fileitem中封装的是普通输入项的数据                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{//如果fileitem中封装的是上传文件                    //得到上传的文件名称,                    String filename = item.getName();                    System.out.println(filename);                    if(filename==null || filename.trim().equals("")){                        continue;                    }                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt                    //处理获取到的上传文件的文件名的路径部分,只保留文件名部分                    filename = filename.substring(filename.lastIndexOf("\\")+1);                    //获取item中的上传文件的输入流                    InputStream in = item.getInputStream();                    //创建一个文件输出流                    FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);                    //创建一个缓冲区                    byte buffer[] = new byte[1024];                    //判断输入流中的数据是否已经读完的标识                    int len = 0;                    //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据                    while((len=in.read(buffer))>0){                        //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中                        out.write(buffer, 0, len);                    }                    //关闭输入流                    in.close();                    //关闭输出流                    out.close();                    //删除处理文件上传时生成的临时文件                    item.delete();                    message = "文件上传成功!";                }            }        }catch (Exception e) {            message= "文件上传失败!,请重新上传";            e.printStackTrace();        }        response.setCharacterEncoding("UTF-8");        response.setContentType("application/json; charset=utf-8");        String jsonStr = "{\"message\":\"" + message  + "\"}";        PrintWriter out = null;        try {            out = response.getWriter();            out.write(jsonStr);        } catch (IOException e) {            e.printStackTrace();        } finally {            if (out != null) {                out.close();            }        }    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req, resp);    }

上传功能还有很多种方式,但大多都是需要commons-fileupload-1.3.3.jar、commons-io-2.4.jar这两个个包的,其中包含丰富的功能。文件上传的请求方式比较特殊,Servlet请求的两种大类,一种是表单形式,另外一种就是非表单形式,常用于文件上传。其实文件上传还可以衍生出来很多,比如比较实用的断点续传功能,但由于本人刚入门不算太久,尝试过几次还没有能实现的案例,暂且不谈,后续肯定会进行补充。


(三)文件下载

可以参考另外一篇文章:http://blog.csdn.net/adelaide_guo/article/details/77757132;

另外如果结合本篇还可以更少行代码

    String file_path = request.getParameter("file_path");    String path = "E:\\工作文件\\开发文档内容\\";    if (file_path != null) {        path = "E:\\工作文件\\开发文档内容\\" + file_path;    }    InputStream inputStream = null;    ServletOutputStream out = null;    try {        File file = new File(path);        String odexName = file.getName();        int fSize = Integer.parseInt(String.valueOf(file.length()));        response.setCharacterEncoding("utf-8");        response.setContentType("application/x-download");        response.setHeader("Accept-Ranges", "bytes");        response.setHeader("Content-Length", String.valueOf(fSize));        response.setHeader("Content-Disposition", "attachment;fileName=" + odexName);        inputStream = new FileInputStream(path);        long pos = 0;        if (null != request.getHeader("Range")) {            // 断点续传            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);            try {                pos = Long.parseLong(request.getHeader("Range").replaceAll("bytes=", "").replaceAll("-", ""));            } catch (NumberFormatException e) {                pos = 0;            }        }        out = response.getOutputStream();        String contentRange = new StringBuffer("bytes ").append(pos + "").append("-").append((fSize - 1) + "").append("/").append(fSize + "").toString();        response.setHeader("Content-Range", contentRange);        inputStream.skip(pos);        byte[] buffer = new byte[1024 * 1000];        int length = 0;        while ((length = inputStream.read(buffer, 0, buffer.length)) != -1) {            out.write(buffer, 0, length);            Thread.sleep(100);        }    } catch (Exception e) {        e.printStackTrace();    } finally {       try {           if (null != out) out.flush();               if (null != out) out.close();               if (null != inputStream) inputStream.close();       } catch (IOException e) { }      }
这样的断点续传可以在浏览器中进行,通常浏览器自带的下载插件都可以实现断点下载,但是浏览器关闭后,下载内容删除,想要全方位实现断点下载功能,目前我能做到的只有起一个客户端,也就是上面那篇文章当中那样,但是有点过于繁琐,也不现实在一个web项目中,。关于源码,我会重新整理并进行上传。

阅读全文
0 0
原创粉丝点击