java中文件上传

//文件上传,和下载
//1,分为两大类。CLOB和BLOB文件,clob是指大文本数据,比如视频,音乐文件等;blob是指二进制文件方式传输(即可以放一切文件)。
处理大型数据:
①存储路径,通过jdbc存储文件路径,然后根据IO操作处理。
②直接将文件存入数据库。CLOB和BLOB文件方式来处理。

//clob实现
//upload.jsp
在这里插入图片描述

文件说明:

//动态多文件上传,服务端逻辑是一样的,只需要在客户端,实现多文件上传控件即可
在这里插入图片描述

在这里插入图片描述

//加入commons-fileupload工具类
//文件上传的服务器,UploadServlet,新建在
$pageContext.request.contextPath/Servlet/UploadServlet路径下

public class UploadServlet extends HttpServlet{
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
	
	//创建文件上传工厂类实例对象
	DiskFileItemFactory factory = new DiskFileItemFactory();
	//创建文件上传的ServletFileUpload实例对象
	ServletFileUpload upload= new ServletFileUpload(factory );
	upload.setFileMax(1024*10)
	//利用ServletFileUpload实例对象upload解析request里的文件内容 
	//try{
		List<FileItem> items=upload.parseRequest(request);
		
		//读取数组中的数据
		for(FileItem fileitem:items){
			//1,数据不能为空.上面省略这个判断;2,不为空时,区分普通项和文件项
			//通过FileItem.isFromField()方法判断,true为普通项,false为文件项
			
			if(fileitem.isFromField()){
				String fileName =fileitem.getFileName();//获取普通想的name属性值
				String fileValue =fileitem.getString();//获取文本内容
				System.out.println(fileName+":"+fileValue);
			}
			else{
				//文件项,获取上传文件名称getName()
				String fileName =fileitem.getName();
				//获取上传文件输入流getInputStream()
				InputStream in =fileitem.getInputStream();
				//此处上传文件是自定义路径,这样是很危险的,例如上传一个包含恶意代码jsp文件,
				
				//因此上传到WEB-INF目录中,在浏览器中不能访问WEB-INF目录中的内容
				String realPath=getServletContext().getRealPath("/uploads");
				
				OutputStream out =new FileOutputStream(new File(realPath,fileName));
				IOUtils.copy(in,out);//将上传文件进行保存。
				in.close();
				out.close();
			}
		}
	   //}		
}
public void doPost(HttpServlet request,HttpServletResponse) throws ServletException,IOException{
	doGet(request,response);
}

}

//上传文件同名处理,为每一个上传文件增加一个UUID,UUID类中的randomUUID()可以生成一个唯一标示符
fileName=UUID.randomUUID().toString()+fileName;

//上传文件乱码问题
1,利用request对象的,setCharacterEncoding(“UTF-8”);写在doGet()和doPost()的前面;
2,利用ServletFileUpload,setCharacterEncoding(“UTF-8”);

//一个目录不能存放过多的文件
1,根据上传时间进行分离,2,根据上传用户进行目录分离,3,按固定数量进行分离,4,按照唯一文件名的hashCode进行分离

//上传单个文件的大小限制
1,利用ServletFileUpload类的setFileMax(long);例:ServletFileUpload.setFileMax(1024*10),设置为10kb;

//上传文件总大小的问题
//利用多文件上传时,还需要设置文件的总大小。利用ServletFileUpload类的setSizeMax(long);

//文件缓存大小,和临时目录。一般上传文件都是存储在内存中,然后在拷贝到服务器磁盘中,但是如果文件过大,就需要手动的设置文件缓存大小
//和上传文件临时目录
手动修改上传文件大小及临时目录:
1,DiskFileItemFactory.setSizeThreshold(缓存字节数);默认缓存字节数10kb;
2,DiskFileItemFactory.setRepository(new File(getServletContext().getRealPath(临时目录相对路径)),如果需要删除临时目录下的文件,
调用FileItem的delete()方法即可。
例子:factory.setSizeThreshold(1024*1024);factory.setRepository(newFile(getServletContext().getRealPath(/tmp));
逻辑机制:当文件上传成功后,删除临时目录中的临时文件。

//流的选择,最好选择bufferdInputStream和bufferdOutputStream

//文件上传进度监听,实时看到进度,可以使用ServletFileUpload提供的setProgressListener()方法,在客户端配合ajax技术实现
需要监听:1,(useTime)已用时间=当前时间-开始时间,2,(speed)速度=已传大小/已用时间,
3,(restBytes)剩余大小=总大小-已经上传大小,4,(restTime)剩余时间=剩余大小/速度

//增加监听
 //long pBytesRead:此时已经能上传的文件大小,long pContextLength:上传文件的总大小,int pItems:				当前上传文件,是表单里的第几个元素
upload.setProgressListener(new ProgressListener){
public void update(long pBytesRead,long pContextLength,int pItems){
	long currentTime = System.currentTimeMills();//当前时间
	long useTime = currentTime - startTime;
	long speed = pBytesRead /pBytesRead;
	long restBytes= pContextLength - pBytesRead;
	long restTime = restBytes/speed;
}

}

实例:

//1,index.jsp

//2.fileupload.jsp
<body>
<from action="...../FileUploadServlet" method="post" enctype="mutliport/from-data">
	文件说明:〈input type="text" name="fileName"〉</br>
	<input type="file" value="upload"> </br>
	<input type="submmit" value="上传">
<from>
//服务端
pubic class FileUploadServlet extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
	request.setCharacterEncoding("UTF-8");
	//创建文件上传工厂
	DiskFileItemFactory factory = new DiskFileItemFactory();
	//设置缓存大小
	factory.setSizeThreshold(1024*1024);
	//得到上传文件目录
	String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
	//上传时生成临时文件保存目录
	String tempPath = this.getServletContext().getRealPath("/WEN-INF/temp");
	File file = new File(tempPath);
	if(file.exists()){
	//创建临时目录
	file.mkdirs();		
	}
	//临时文件目录
	//factory.setRepository(new File(getServletContext().getRealPath("/tmp")));
	//创建Servlet文件上传实例对象
	ServletFileUpload upload = ServletFileUpload(factory);
	final long startTime = System.currentTimeMills();
	//为上传文件增加进程监听
	upload.setProgressListener(new ProgressListener()){
		public void uploadProgress(long pBytesRead,long pContextLength,int pItems){
			long currentTime = System.currentTimeMills();//当前时间
			long useTime = currentTime - startTime;
			long speed = pBytesRead /pBytesRead;
			long restBytes= pContextLength - pBytesRead;
			intrestTime = restBytes/speed;
		}
	}
	try{
		//限制上传单个3M和总大小10M
		upload.setFileSizeMax(1024*1024*3);
		upload.setSizeMax(1024*1024*10);

		List<FileItem> iteams =upload.praseRequest(request) ;
		if(!(iteams==null)){
			for(FileItem fileItem :iteams ){
				if(fileItem.isFromFile){
					String fileName = fileItem.getFileName();
					String fieldValue = fileItem.getString();
					System.out.println(fileName+":"+fieldValue);
				}else{
					String fileName = fileItem.getName();
					//解决浏览器过旧问题
					int index = fileName.lastIndexOf("\\");
					if(index>=0){fileName.substring(index+1);}
					//防止文件同名
					fileName = UUID.randomUUID().toString+fileName;
					InputStream in = fileItem.getInputStream(); 
					//利用hashcode进行目录分离,hasCode根据对象的地址或字符串或者数字算出来的int类型的数值;
					int hascode = fileName.hasCode();
					//生成一级目录
					int d1 = hashcode&0xf;
					//生成二级目录
					int d2 = (hashcode>>>4)&0xf;
					String realPath = getServletContext().getRealPath("/WEB-INF/uploads/"+d1+"/"+d2);
					//boolen mkdir()创建此抽象path的目录;mkdirs()创建此抽象路径名指定的目录,包括创建必须但不存在的父目录
					//用法:1,file.mkdirs("/a/aa/aaa");file是一个File对象。2,在申明时,就加入File file=new File("/a/aa/aaa");
					new File(realPath).mkdirs();
					BufferdOutputStream out = new FileBufferdOut(new File(realPath,fileName));
					IOUtils.copy(in,out);
					in.close();
					out.close();
				}
			}
		}catch(Exception e){
			//设置传给前台的setError,setSuccess
		}
	} 
}

public void doPost(HttpServletRequest request,HttpServletResponse response){
	request.setCharacterEncoding("UTF-8");
	doGet(request,response);
}

}

猜你喜欢

转载自blog.csdn.net/weixin_42603009/article/details/86760943