文件上传和下载-程序员宅基地

技术标签: java  测试  数据结构与算法  

一.文件的上传
(一)基本概念及其入门案例
1.什么是文件上传:将本地的文件上传到服务器端。
2.应用:百度网盘,上传照片,上传附件。
3.javaweb端实现文件上传;
客户端:需要文件的输入项 <input type="file"/>
必须有三点设置:
1)type="file" name 必须有 name="myfile"
2)form表单 method="post"提交方式 (get参数显示在url上,get数据大小1k)
3)form表单 enctype="multipart/form-data" 编码格式
服务端:写一段文件上传的程序。
requestl.getInputStream(); 获取输入流
System.out.write();

4.fileupload 文件上传的组件
1)jspsmartupload 上传组件,嵌入在jsp中。model1时代,jsp。
2)jsp+servlet时代 fileuplaod

5.fileupload的jar commons-fileupload-1.2.1jar包和commons-io-1.4jar包 要一起使用。 依赖。

package cn.itcast.servlet;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.itcast.util.UploadUtil;

public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String filedesc = request.getParameter("filedesc");
        System.out.println("文件描述:"+filedesc);
        // 获取输入流
        //InputStream in = request.getInputStream();
        // 打印控制台上
        /*int b;
        while((b = in.read()) != -1){
            System.out.write(b);
        }
        System.out.flush();*/
        
        if(!ServletFileUpload.isMultipartContent(request)){
            throw new RuntimeException("请设置正确的enctype");
        }
        
        /**
         * 1.创建磁盘文件项工厂
         */
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置内存缓冲区的大小
        factory.setSizeThreshold(2*1024*1024);  //2M
        // 设置临时文件的存储位置
        String temppath = this.getServletContext().getRealPath("/temp");
        File filetemp = new File(temppath);
        factory.setRepository(filetemp);
        
        /**
         * 2.创建文件上传类
         */
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置上传文件的总大小
        upload.setSizeMax(50L*1024*1024); // 50M
        // 设置文件名称的编码
        upload.setHeaderEncoding("UTF-8");
        
        /**
         * 3.解析request
         */
        try {
            List<FileItem> list = upload.parseRequest(request);
            /**
             * 4.循环遍历list集合,拿到fileItem对象,判断是否普表单项
             */
            for (FileItem fileItem : list) {
                // isFormField()
                if(fileItem.isFormField()){
                    // 普通表单项
                    // 获取参数的名称
                    String name = fileItem.getFieldName();
                    // 获取值
                    //String value = fileItem.getString();
                    String value = fileItem.getString("UTF-8");
                    System.out.println(name+" = "+value);
                }else{
                    // 文件上传项
                    // 获取文件的名称
                    String filename = fileItem.getName();
                    // 先判断filename不能空
                    if(filename == null || filename.trim().length() == 0){
                        throw new RuntimeException("请选择文件");
                    }
                    // 解决IE6的问题  D:\class\resource\hello.txt
                    int index = filename.lastIndexOf("\\");
                    if(index != -1){
                        filename = filename.substring(index+1);
                    }
                    //解决文件名重名的问题
                    filename = UUID.randomUUID().toString()+"_"+filename;
                    // 目录分离
                    String dir = UploadUtil.getRanromDir(filename);
                    
                    System.out.println("文件名称:"+filename);
                    // 获取输入流
                    InputStream in = new BufferedInputStream(fileItem.getInputStream());
                    // 先获取upload的绝对路径
                    String filepath = this.getServletContext().getRealPath("/upload"+dir);
                    // 创建多级目录
                    new File(filepath).mkdirs();
                    // 创建file对象
                    File file = new File(filepath,filename);
                    // 输出流
                    OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
                    int b;
                    while((b = in.read()) != -1){
                        os.write(b);
                    }
                    os.close();
                    in.close();
                    // 删除临时文件(必须写在流关闭之后)
                    fileItem.delete();
                }
            }
            
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        System.out.println(System.getProperty("java.io.tmpdir"));
    }

}

 


(二)入门案例存在的问题
1.IE6上传文件的问题:
产生原因:把文件的绝对路径传过来了。
解决办法:切割。把文件名称切出来。
// 解决IE6的问题 D:\class\resource\hello.txt
int index = filename.lastIndexOf("\\");
if(index != -1){
filename = filename.substring(index+1);
}
2.注意事项(*****)
String filedesc = request.getParameter("filedesc"); 在文件上传 enctype="multipart/form-data"拿不到值了。
想拿到值就下面方法。
// 获取参数的名称
String name = fileItem.getFieldName();
// 获取值
String value = fileItem.getString();

(三)文件上传的核心类及其API
1.磁盘文件项工厂类 DiskFileItemFactory
1)DiskFileItemFactory(int sizeThreshold, java.io.File repository) 第一个参数内存缓冲区的大小 第二个参数临时文件的存储位置
内存缓冲区:上传文件时,文件首先会上传到内存缓冲区中,上传的文件的大小超过设置的内存缓冲区的大小,就会产生临时文件。
临时存储位置:用来保存临时文件的。

2)void setSizeThreshold(int sizeThreshold) 设置内存缓冲区的大小 默认10k
3)void setRepository(java.io.File repository) 设置临时文件存储位置 System.getProperty("java.io.tmpdir") C:\Users\ADMINI~1\AppData\Local\Temp\

2. 文件上传类 ServletFileUpload
1)static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request) 判断enctype是否是multipart方式
2)java.util.List parseRequest(javax.servlet.http.HttpServletRequest request) 解析request 返回list<FileItem>集合
3)void setSizeMax(long sizeMax) 设置上传所有文件的总大小 和 void setFileSizeMax(long fileSizeMax) 设置单个上传文件的大小
4)(*****)void setHeaderEncoding(java.lang.String encoding) 设置编码 可以解决中文文件名乱码的问题
5)void setProgressListener(ProgressListener pListener) 设置进度条的监听器 进度条速度 剩余时间 剩余大小

3. 文件项FileItem
1)boolean isFormField() 判断是否是普通表单项还是文件上传项
if(fileItem.isFormFiele()){
// 表单
2)java.lang.String getFieldName() 获取参数的名称
3)java.lang.String getString() 获取值
4)(*****)java.lang.String getString(java.lang.String encoding) 设置表单中文的编码 解决普通表单项的中文乱码的问题
}else{
// 文件
5)java.io.InputStream getInputStream() 获取输入流
6)java.lang.String getName() 获取文件名称
}
7)void delete() 删除临时文件((必须写在流关闭之后))

(四)多文件上传案例(js控制)
需求:多文件上传。

(五)上传文件的扩展
1.上传文件存放目录问题:
1)在webroot目录下,安全级别较低,允许用户直接访问。
购物商城的网站:京东。

2)上传文件目录访问WEB-INF目录下,安全级别较高。通过程序。
例子:视频网站。

2.文件名重名的问题
解决办法:UUID+"_"+文件名称

3.解决一个目录内文件过多的问题(目录分离算法)
1)根据上传文件的时间(周,月)
2)根据上传文件的数量(3000)
3)根据用户创建一个文件夹(张三,李四)
4)根据唯一文件名的hashcode值算法。


二.文件的下载
(一)基本概念及其入门案例
1.什么的文件的下载:将服务器的文件下载到本地。
2.应用:百度网盘,下载歌曲,下载图片。
3.javaweb实现文件的下载:
1)超链接下载 <a href="文件的绝对路径">文件名称</a>
浏览器可以解析你文件的格式。浏览器直接打开。

2)程序的文件下载。
接收文件的名称,获取download的绝对路径,并且拼接file对象,读入到输入流中。
两点注意:两个头一个流
两个响应头:设置Content-Type 属性 MIME类型
设置Content-Disposition 值attachment;filename= + 文件名称 以附件的形式打开。
一个响应流:向浏览器输出 response.getOutputStream()

(二)文件下载扩展案例
需求:在磁盘随便指定一个目录,要把该目录下的所有文件及其子目录下的所有文件列在页面上,并且提供下载。
采用广度非递归的遍历,依赖于数据结构。队列 FIFO 先进先出 JDK5.0 提供了接口 Queue

package cn.itcast.servlet;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 下载的入门案例
 * @author Administrator
 *
 */
public class DownloadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取文件的名称
        String filename = request.getParameter("filename");
        // 获取download的绝对路径
        String filepath = this.getServletContext().getRealPath("/download");
        // 创建file对象
        File file = new File(filepath,filename);
        // 读入到输入流
        InputStream in = new BufferedInputStream(new FileInputStream(file));
        // 设置两个头
        String mimeType = this.getServletContext().getMimeType(filename);
        // 设置类型
        response.setContentType(mimeType);
        // 设置以附件形式打开
        response.setHeader("Content-Disposition", "attachment;filename="+filename);
        // 输出流
        OutputStream os = response.getOutputStream();
        int b;
        while((b = in.read()) != -1){
            os.write(b);
        }
        os.close();
        in.close();
    }

}

 


2.get方式提交 中文乱码
filepath = new String(filepath.getBytes("ISO-8859-1"),"UTF-8");

3.IE6中文乱码
产生原因:代码没有问题。IE6对中文的编码有bug。
解决办法:自己编码。URLEncoder.encode(f.getCanonicalPath(), "UTF-8")

4.弹出的下载框显示的中文乱码


三.JavaMail(邮件)
(一)邮件的基本概念及其传输过程
1.为什么学习邮件:比较好的用户体验,比较火的技术。
2.常见邮件:祝福邮件,通知邮件,垃圾邮件

3.基本概念
1)邮件服务器:是一台电脑,装关于邮件服务器的软件。收发邮件。
2)电子邮箱:邮件服务器上的账号,在邮件服务器分配一块空间,用来保存邮件。

3)邮件的传输协议:
发送邮件协议:SMTP协议 默认端口 25

接收邮件协议:POP3协议 默认端口 110

接收邮件协议:IMAP协议 默认端口 143
区别:允许不用下载,直接在服务器端可以修改。
gmail 支持IMAP

4.邮件的传输过程
看图七

(二)通过telnet命令手动发送邮件(网络)
1.如果是win7的系统,需要手动开启telnet命令。如果xp不用。
2.发送邮件的协议(SMTP)
1)telnet smtp.sina.com 25 链接新浪的发送邮件的服务器
2)ehlo hi 打个招呼
3)auth login 是否需要登陆认证
4)输入用户名 (必须要经过BASE64进行编码)
5)输入密码
6)mail from:<[email protected]> 发件人
7)rcpt to:<[email protected]> 收件人
8)Data RFC822文档(规范)
9)输入邮件内容(RFC822文档)
10). 代表邮件的结束
11)quit 断开链接


3.RFC822文档
包含邮件头 和邮件体,中间用空行分隔。
邮件头:
from:<[email protected]> 发件人
to:<[email protected]> 收件人
subject:girl 邮件的标题

邮件体:
I LOVE YOU TOO TOO

4.接收邮件的协议 POP3协议
telnet pop3.163.com 110 链接接收邮件服务器
user 输入用户名
pass 输入密码
stat 返回邮件的数量
list 返回邮件列表结合
retr 2 访问第二封邮件
quit 端口链接

(三)邮件服务器,客户端安装及其telnet命令发送邮件(本机)
1.安装邮件服务器
配置:工具--服务器设置--修改域名(estore.com)
新建账号:账号--新建账号。

2.安装客户端软件
安装foxmail。
配置:建立新的账户:[email protected] 密码111
指定邮件服务器:localhost


(四)通过JavaMail创建简单的邮件
1.javamial sun官方提供api,关于邮件的api。
2.下载jar包 javamail1_4_4和jaf-1_1_1 包,必须一起使用,依赖。
JDK6.0之后 jaf内置。如果是JDK1.6版本之前,需要引入jaf的包。

3.入门案例。
1)Session 链接服务器会话。
2)Message 邮件对象
3)Transport 发送邮件工具类

4.邮件的内容打印在控制台上保存
java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
产生的原因:myeclipse自带的jar与javamail的jar包冲突导致。
解决办法:

转载于:https://www.cnblogs.com/appium/p/10276427.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30639719/article/details/99210630

智能推荐

1093 奖学金-程序员宅基地

文章浏览阅读81次。1093 奖学金难度:普及-题目类型:模拟提交次数:1涉及知识:结构体,stable_sort题目描述某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,这样,每..._全学年各科成绩平均分在85分以上(含85分),单科考试或考查成绩均不低于80分者,

深入理解浏览器最小渲染单位以及border设置0.5px_浏览器渲染的最小像素-程序员宅基地

文章浏览阅读2.5k次。# 首先我们讨论一下关于border最小的值的问题上边这张是在安卓手机中的效果,下边这张是在浏览器中的效果明明相同的代码却导致不同的效果,那么老规矩上测试代码,很简单就是暴力测试,可以自己复制试一下,ios中和浏览器的效果一样就不贴图了<!DOCTYPE html><html><head> <title>demo exam..._浏览器渲染的最小像素

鲸鱼算法(WOA)优化极限学习机ELM回归预测,WOA-ELM回归预测,多变量输入模型-程序员宅基地

文章浏览阅读728次,点赞13次,收藏16次。在机器学习领域,回归预测是一项重要的任务,它可以帮助我们预测未来的趋势和结果。极限学习机(ELM)是一种快速而有效的机器学习算法,它在回归预测任务中表现出色。然而,为了进一步提高其性能,我们可以结合鲸鱼算法(WOA)进行优化,从而实现更准确的数据回归预测。鲸鱼算法是一种基于自然界鲸鱼觅食行为的优化算法,它模拟了鲸鱼在寻找食物时的行为,通过调整自身位置来寻找最优解。结合鲸鱼算法和极限学习机,可以有效地优化ELM模型的权重和偏置,从而提高回归预测的准确性和稳定性。

VC++常规错误之21:Debug Assertion Failed!在winocc.cpp第307或329行错误 断言错误,如图所示_vc++显示调试断言失败-程序员宅基地

文章浏览阅读7.9k次,点赞2次,收藏10次。VC++常规错误之21:Debug Assertion Failed!在winocc.cpp第307或329行错误断言错误,如图所示找到代码(这个是VS2010版本的,各个版本会有所不同,可能不是在第329行,但是都是这个意思),如下BOOL CWnd::ShowWindow(int nCmdShow){ ASSERT(::IsWindow(_vc++显示调试断言失败

Chrome插件抓取大法揭秘,助你玩转浏览器_chrome 抓包 扩展-程序员宅基地

文章浏览阅读147次。本文将介绍如何抓取Chrome插件,以及其重要性和使用方法。1.插件的定义和作用:Chrome插件是一种为浏览器增加功能和扩展能力的软件。它们可以帮助用户提升浏览器的功能,提供更好的用户体验。2.抓取插件的意义:抓取Chrome插件可以帮助用户发现并获取适合自己需求的插件。通过抓取_chrome 抓包 扩展

完美解决source insight 4.0无法跳转问题6以及如何跳转问题_sourceinsight 本页c++代码不能跳转-程序员宅基地

文章浏览阅读7.8k次,点赞6次,收藏13次。如果没有工程的新建工程,如果已经有的,点击project setting设置源码的保存位置点击添加或者删除工程的文件递归添加文件路径到工程如果要删除,点击这个按钮加载工程等待完成即可跳转方式:按住ctrl +鼠标左键点击关键字..._sourceinsight 本页c++代码不能跳转

随便推点

《设计师要懂心理学》-第二章-人如何阅读-程序员宅基地

文章浏览阅读129次。第二章 人如何阅读  如今世界成人识字率已超过80%。对很多人来说,阅读是主要的沟通手段。但我们是如何阅读的?对此,设计师应该了解什么呢?13.大写单词难读之谜  Kenneth Paap(1984)与Keith Rayner(1998)的研究表明,阅读时我们其实是在识别和预想字母,然后根据字母认出单词。要点:1)阅读并非看上去那么流畅 阅读时,我们会觉..._人们偏好较小的行宽并且喜欢

SQL 数据查询语句_查询每个雇员的情况及其工作部门的情况-程序员宅基地

文章浏览阅读4.7k次,点赞6次,收藏63次。《数据库系统 》 实验报告实验名称 SQL 数据查询语句 实验地点 实验楼423 实验日期一、实验目的及要求掌握SELECT 语句的基本语法和查询条件表示方法掌握GROUP BY 和ORDER BY 子句的作用和使用方法掌握连接查询和子查询的使用方法二、实验环境Windows 10 SQLSERVER 2008三、实验内容实验任务一:1.对上节建立的表输入数据:Departments 表:Employee 表:Salary表信息:_查询每个雇员的情况及其工作部门的情况

BCGControlBar的使用_bcgcontrolbar 编译 static release-程序员宅基地

文章浏览阅读714次。安装 BCGControlBar 库到你的计算机:解压缩 BCGControlBar.zip (比如,到 c:/bcg 目录中)把 c:/bcg/bin 增加到你的 path 环境变量中,运行 Visual C++ 并且打开 Tools | Options 对话框,切换到Directories 页并且把 c:/bcg/bcgcontrolbar 加入到 include 目录 中,把 c_bcgcontrolbar 编译 static release

深度学习论文:Deep learning-Yann LeCun-Nature 2015_deep learning yann lecun-程序员宅基地

文章浏览阅读4.7k次,点赞10次,收藏40次。Deep learning(Yann LeCun, Yoshua Bengio & Geoffrey Hinton)doi:10.1038/nature14539Abstract:Deep learning allows computational models that are composed of multiple processing layers to learn representations of data with multiple levels of abstra._deep learning yann lecun

linux 文件删除命令_ll丨∴-程序员宅基地

文章浏览阅读579次。使用这个rm -rf删除文件的时候一定要格外小心,linux没有回收站的。直接rm就可以了,不过要加个参数-f 即:rm -f 文件路径-f 就是直接强行删除,不作任何提示的意思删除文件使用实例:rm -f /var/log/httpd/access.log将会强制删除/var/log/httpd/access.log这个文件删除目录使用实例:rm -rf /var/log/httpd/access将会删除/var/log/httpd/access目录以及其下所有文件、文件夹需要提醒的是:使用这个rm _ll丨∴

HTML---学习笔记_使用html表格标签及其他所学标签,自行设计表格页面结构,完成个人信息的展示。要求-程序员宅基地

文章浏览阅读224次。HTML学习笔记一、Web标准1、为什么需要Web标准?浏览器不同,它们显示页面或者排版就会有些许差异,所以需要一套标准来规范。2、Web标准的构成主要包括结构(Structure)、表现(Presentation)和行为(Behavior)三个方面。标准说明结构结构用于对网页元素进行整理和分类,现阶段主要学的是HTML表现表现用于设置网页元素的版式、颜色、大小等外观样式,主要指的是CSS行为行为是指网页模型的定义及交互的编写,现阶段学的主要是JavaScr_使用html表格标签及其他所学标签,自行设计表格页面结构,完成个人信息的展示。要求

推荐文章

热门文章

相关标签