百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

Java文件上传与下载_java文件上传与下载一样吗

yund56 2025-02-25 00:49 14 浏览


1 文件上传

1.1 文件上传入门

1.1.1 实现文件上传条件

1)表单的提交方式必须是POST方式。(才有content-type属性)

2)有文件上传表单,表单中有的选择文件的标签

3)把表单设置为enctype="multipart/form-data",提交的数据不再是key-value对,而是字节数据

<form action="${pageContext.request.contextPath }/UploadDemo1" method="post" enctype="multipart/form-data">

请选择文件: <input type="file" name="img"/><br/>

<input type="submit" value="上传" />

form>

1.1.2 手动解析上传文件

/**

* 手动处理上传文件的逻辑

* @author APPle

*/

public class UploadDemo1 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//得到实体内容数据

InputStream in = request.getInputStream();

BufferedReader br = new BufferedReader(new InputStreamReader(in));


//读取文件的开始符

String startTag = br.readLine();


//读取文件名: Content-Disposition: form-data; name="img"; filename="news.txt"

String line = br.readLine();

String fileName = line.substring(line.lastIndexOf("filename=\"")+10, line.lastIndexOf("\"") );

System.out.println("文件名:"+fileName);


//跳过2行

br.readLine();

br.readLine();


//读取文件的实际内容

String str = null;

BufferedWriter bw = new BufferedWriter(new FileWriter("E:/files/"+fileName));

while((str=br.readLine())!=null){

//读到文件结束符时退出循环

if((startTag+"--").equals(str)){

break;

}


//把内容写出文件中

bw.write(str);

bw.newLine();

bw.flush();

}

//关闭

bw.close();

br.close();

}


public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

1.2 工具实现文件上传

1.2.1 commons-fileupload组件概述

commons-fileupload是Apache组织旗下的开源的文件上传的组件。使用非常简单易用。

1.2.2 核心的API

DiskFileItemFactory类: 用于创建上传对象,设置文件缓存区大小,设置文件缓存目录。

ServletFileUpload类: 用于在Servlet程序中实现文件上传

List list = parseRequest(request): 用于解析请求数据,提取和封装文件信息。

FileItem类: 封装一个文件的所有相关的信息javabean。包含文件名称,文件大小,文件类型, 文件数据内容。

1.2.3 fileUpload开发步骤

1)导入commoms-fileuload的jar包


commons-fileupload-1.2.2.jar 核心包

commons-io-2.1.jar 辅助包

2)编写程序

1.3 实现单文件上传

//1.创建DiskFileItemFactory类

/**

* 参数一: 表示文件缓存区的大小。如果上传的文件没有超过缓存区大小,则文件不缓存;否则缓存文件,缓存到临时目录。(byte)

* 参数二: 表示缓存区的临时目录。

*/

DiskFileItemFactory factory = new DiskFileItemFactory(10*1024,new File("e:/temp/"));


//2.创建ServletFileUpload类

ServletFileUpload upload = new ServletFileUpload(factory);


/**

* 设置文件名的编码

*/

upload.setHeaderEncoding("utf-8");


//3.解析request数据(把每一个文件封装到FileItem对象中,FileItem放入List中)

try {

List list = upload.parseRequest(request);


//取出第一个上传的文件

FileItem file = list.get(0);

//得到文件名(getName())

String fileName = file.getName();

//得到文件大小

long fileSize = file.getSize();

//得到内容类型

String contentType = file.getContentType();

//得到文件数据内容

InputStream in = file.getInputStream();


/**

* 4.把文件数据内容存储到服务器端的硬盘中

*/

FileUtils.copyInputStreamToFile(in, new File("e:/files/"+fileName));


/**

* 5.文件上传完毕,手动清理缓存文件

*/

file.delete();


System.out.println("文件名:"+fileName);

System.out.println("文件大小:"+fileSize);

System.out.println("文件类型:"+contentType);

System.out.println("文件数据内容:"+in);


} catch (FileUploadException e) {

e.printStackTrace();

}

1.4 实现多文件上传

//1.创建DiskFileItemFactory对象

DiskFileItemFactory factory = new DiskFileItemFactory(10*1024, new File("e:/temp/"));

//2.创建ServletFileUpload对象

ServletFileUpload upload = new ServletFileUpload(factory);

//3.设置文件编码

upload.setHeaderEncoding("utf-8");

//4.开始解析文件

try {

List list = upload.parseRequest(request);

if(list!=null){

List ufList = new ArrayList();

//遍历多个文件

for(FileItem file: list){

//取出文件相关信息

String fileName = file.getName();

long fileSize = file.getSize();

String contentType = file.getContentType();

//封装到javabean

UploadFile uf = new UploadFile();

uf.setFileName(fileName);

uf.setFileSize(fileSize);

uf.setFileType(contentType);

//放入list中

ufList.add(uf);


//把文件保存到服务器端的硬盘

FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+fileName));

//删除缓存文件

file.delete();

}

request.setAttribute("ufList", ufList);

request.getRequestDispatcher("/success.jsp").forward(request, response);

}

} catch (FileUploadException e) {

e.printStackTrace();

}

1.5 动态选择多文件上传

<html>

<head>

<title>使用组件实现动态多文件上传title>

head>

<body>

<form action="${pageContext.request.contextPath }/UploadDemo3" method="post" enctype="multipart/form-data" name="uploadForm">

<table border="1" width="400px">

<tbody>

<tr id="1">

<td>

请选择文件:

td>

<td>

<input type="file" name="file"/><input type="button" value="删除" onclick="delItem(1)"/>

td>

tr>

tbody>

<tr>

<td colspan="2"><input type="button" value="添加" onclick="addIten()"/>td>

tr>

<tr>

<td colspan="2"><input type="button" value="上传" onclick="checkSunbit()"/>td>

tr>

table>

form>


<script type="text/javascript">

var id = 2;

//添加一行

function addIten(){

var trNode = document.createElement("tr");

trNode.setAttribute("id", id);


var tdNode1 = document.createElement("td");

tdNode1.innerHTML = "请选择文件:";


var tdNode2 = document.createElement("td");

var input1 = document.createElement("input");

input1.setAttribute("type", "file");

input1.setAttribute("name", "file");

var input2 = document.createElement("input");

input2.setAttribute("type", "button");

input2.setAttribute("value", "删除");

input2.setAttribute("onclick", "delItem("+id+")");

tdNode2.appendChild(input1);

tdNode2.appendChild(input2);


trNode.appendChild(tdNode1);

trNode.appendChild(tdNode2);


var tbodyNode = document.getElementsByTagName("tbody")[0];

tbodyNode.appendChild(trNode);


id++;

}


//删除一行(根据tr的id值删除)

function delItem(id){

if(id>1){

var trNode = document.getElementById(id);

var tbodyNode = document.getElementsByTagName("tbody")[0];

tbodyNode.removeChild(trNode);

id--;

}

}


//提交并且检查file属性

function checkSunbit(){

//检查file属性是否全部填上

var fileList = document.getElementsByName("file");

for(var i=0;i

//如果为选择file,则其value值为空

if(fileList[i].value==null || fileList[i].value==""){

alert("请选择第"+(i+1)+"个文件");

return;

}

}

//提交表单

var form = document.forms['uploadForm'];

form.submit();

}

script>

body>

html>

1.6 文件上传的细节

1.6.1 限制文件类型

//得到文件类型

String contentType = file.getContentType();

System.out.println(contentType);

//如果是图片,才可以上传(image/bmpjepgjpggif)

if(!contentType.toLowerCase().matches("image/[a-z]*")){

throw new FileTypeErrorException("文件类型不符合条件!");

}

1.6.2 限制上传文件大小

ServletFileUpload类:

setFileSizeMax:设置单个文件的最大容量。

setSizeMax : 设置所有文件的最大容量。

//4.解析请求

try {

List list = upload.parseRequest(request);

if(list!=null){

for(FileItem file : list){

/**

* 限制文件类型

*/

//得到文件类型

String contentType = file.getContentType();

System.out.println(contentType);

//如果是图片,才可以上传(image/bmpjepgjpggif)

if(!contentType.toLowerCase().matches("image/[a-z]*")){

throw new FileTypeErrorException("文件类型不符合条件!");

}


//保存文件

FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+file.getName()));

//删除缓存文件

file.delete();

}

}

} catch (FileTypeErrorException e) {

//e.printStackTrace();

//处理文件类型错误的异常

request.setAttribute("message", e.getMessage());

request.getRequestDispatcher("/05.upload.jsp").forward(request, response);

return;

} catch (FileSizeLimitExceededException e) {

//e.printStackTrace();

//处理文件超过限制的异常

request.setAttribute("message", "单个文件不能超过1M");

request.getRequestDispatcher("/05.upload.jsp").forward(request, response);

return;

} catch (SizeLimitExceededException e) {

//e.printStackTrace();

//处理文件超过限制的异常

request.setAttribute("message", "所有文件不能超过5M");

request.getRequestDispatcher("/05.upload.jsp").forward(request, response);

return;

} catch (FileUploadException e) {

e.printStackTrace();

}

1.6.3 查看文件上传的进度

ServletFileUpload类:

setProgressListener(进度监听器): 设置文件上传的监听器

1.6.4 处理文件名重复问题

/**

* 解决文件名重复问题:

* 1)日期_时间_随机数.jpg

* 2)使用UUID算法(在一台PC都是唯一的)

*/

String fileName = file.getName();

//得到源文件的后缀名

String supfix = fileName.substring(fileName.lastIndexOf(".")); //.jpg

//使用UUID算法生成随机名称

fileName = UUID.randomUUID().toString()+supfix;

1.6.5 把同一个目录的文件打散到不同的目录下

假如所有文件都放在同一个目录下,不方便管理。

1.6.6 得到普通文本控件内容

//判断该FileItem是否是文件还是普通文本空间

if(file.isFormField()){

//普通文本空间(text/password/checkbox/radio/select/texearea

//得到控件内容


//处理一个普通文本

/*String info = file.getString("utf-8");

System.out.println("描述:"+info);*/


//处理多个普通文本

String fieldName = file.getFieldName();

if("info1".equals(fieldName)){

String info1 = file.getString("utf-8");

System.out.println("描述1:"+info1);

}

if("info2".equals(fieldName)){

String info2 = file.getString("utf-8");

System.out.println("描述2:"+info2);

}

}

2 文件下载

2.1 普通文件下载

使用超链接。缺点:1)暴露文件的路径 2)扩展型和安全性不好

2.2 使用servlet程序下载(推荐)

//得到需要下载的文件

String path = this.getServletContext().getRealPath("/upload/9/1/图片1.png");


File file = new File(path);

//读取服务器本地的文件

FileInputStream in = new FileInputStream(file);


/**

* 处理URL编码问题

*/

String fileName = file.getName();

//对文件名进行URl编码

fileName = URLEncoder.encode(fileName, "utf-8");


//判断不同浏览器

String userAgent = request.getHeader("user-agent");

String filefix = null;

if(userAgent.contains("Trident")){

//IE

filefix = "filename="+fileName;

}else if(userAgent.contains("Firefox")){

//Firefox

filefix = "filename*="+fileName;

}else{

filefix = "filename="+fileName;

}


//告诉浏览器以下载方式打开资源

response.setHeader("Content-Disposition", "attachment;"+filefix);


//把本地文件发送给浏览器

byte[] buf = new byte[1024];

int len = 0;

while( (len=in.read(buf))!=-1 ){

response.getOutputStream().write(buf, 0, len);

}

//关闭

in.close();

相关推荐

没有获得Windows 10 20H2升级通知,怎样直接升级

微软公司已经正式发布Windows1020H2操作系统,在正常情况下,微软只会首先推送到少量电脑,然后一边推送一边采集遥测数据。收集遥测数据可以确定哪些电脑可以更新,哪些电脑在更新后可能会失败,微...

不想让人随便卸载你安装的程序,用这四招,他将无计可施

Windows10不提供设置删除应用程序限制的功能,有几种间接方法可以防止用户删除操作系统中的程序和游戏。一、WindowsInstaller服务使用Windows工具,可以部分限制用户的权限。如...

一文看懂苹果全球开发者大会 五大系统全面升级

来源:环球网【环球网智能报道记者张阳】北京时间6月23日凌晨1点,苹果全球开发者大会(WWDC2020)如期举行,还是那个熟悉的乔布斯剧院,依旧是高水准的视频展示,但是这届WWDC,却是苹果历史...

无需等待微软分批推送,23H2可借助注册表快速获取Win11 24H2更新

IT之家10月15日消息,Windows1124H2正在分批推送,但由于存在多种Bug,微软已经开始放缓其推送节奏。WindowsLatest发现,Windows1123H2...

办公小技巧:剑走偏锋 PPT中打造动态图表

年底到了少不了又要制作各种总结报表,为了让自己的报表与众不同,我们可以借助PowerPoint动画组件+报表的方式,打造出更为出彩的动态图表。下面以PowerPoint2016为例,介绍如何使用三维...

文档表格 版本差异何在

在办公过程中,对文档或表格的修改是司空见惯的事。那么,一份文档做了内容改动,如何知道差异在哪里?一份表格改动部分数据,如何知道哪些有所变动?不要说审阅和修订功能,因为不是所有人都会用这些功能来标注的,...

Excel VBA自制日历组件16色可选 完美替代VBA日期控件

本日期组件可跟随单元格跟随窗体中ActiveX文本框组合框控件16种配色可选私信回复880日历可体验效果使用说明1打开自己需要应用日历面板的Excel表,注意必须是启用VBA的格式2在...

如何从交互角度读懂产品需求文档

作为设计师,理解产品经理提供的需求文档是交互设计工作的重要前提与起点,然而对于很多设计师来说,需求文档内容通常非常复杂,设计师们需要花费大量时间去消化、理解和归纳。本文作者结合公司示例,分析设计师如何...

植入让文档变得更强大

有效地利用文档置入技术,会让我们的常用文档功能变得更加强大,实现更加高效或有趣的应用。1.写字板文档嵌入其他文档有时,我们要组织一个大型的文档,但是这些文档的内容可能来自于不同种类的文档编辑器,比如...

Office 2016滚动文本框 顺手就来

【电脑报在线】如果一页PPT内容较多无法在完全显示,就需要用到滚动文本框,在PPT2016中借助控件即可快速制作滚动文本框。在“告诉我你想要做什么”输入“文本框控件”,在搜索结果点击“文本框(Acti...

Axure的多状态复选树

本文将详细介绍如何在Axure中实现一种增强型的多状态复选树组件,它不仅支持全选、半选和未选等状态,还具备动态加载、关键字筛选等高级功能。多状态复选树(Multi-StateCheckboxTre...

办公小技巧:PPT中控件图表巧联动

在利用PPT进行图表演示时,操作者有可能要与图表进行交互联动,比如通过输入数据来预测产品的生产情况等,这时就需要用到“开发工具”中的控件了。几个控件配合几句VBA代码,就可以轻松实现上述交互联动效果(...

用好插件——找回火狐的旧功能

现在的软件,特别是浏览器类软件,更新换代速度都很快,而且无论是外观界面还是系统组件都会有较大的变化,这样会让很多朋友无所适从。以大家常用的火狐浏览器为例,它就已经升级到了最新的35版,而且在新版中对很...

重新认识控件(二)

图片和文字,都是一种数据形式。我平时对文本框的录入,报错和提交的设计比较多。最近涉及到图片控件的设计,细细琢磨一下,这玩意还有一些平时没太注意的细节点,感觉对于其他控件的设计有指导意义,特此总结一下传...

JSA宏教程——在文档中添加复合框控件

上一期,我们初步认识了控件Control,本节我们将继续控件的相关内容。这几期我们将逐一介绍相关控制。本节先介绍复合框(也叫组合框)Combobox。复合框的作用复合框就是一个下拉选项框,一次显示一个...