servlet上传功能前端和后端的实现

本文介绍了如何使用Java Servlet和Ajax实现文件上传功能,包括前端JS监听上传进度、后端Servlet接收文件及删除临时文件的定时任务。通过监听器ServletContextListener处理Web应用生命周期,实现自动清理过期临时文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目需要做一个文件上传功能,做完了分享下,顺带当做笔记。
上传功能用后台用java实现,前端主要是js的ajax实现。后台还加入定时删除临时文件。
效果如图
这里写图片描述
这里写图片描述
首先是上传功能的主要类,下面是代码

package util.upload;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
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 javax.servlet.http.HttpSession;

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

public class UploadServlet extends HttpServlet {
  
 private static final long serialVersionUID = -3100028422371321159L;
 private boolean isAllowed;
 private String upFileName;
	//定义合法后缀名的数组
 private String[] allowedExtName=new String[]
    		{"zip","rar",//压缩文件
		 "txt","doc","wps","docx","java",//文本
		 "xls","xlsx",//表格
		 "ppt","pptx",//幻灯片
		 "pdf",//pdf
		 "jpg","jpeg","bmp","gif","png"//图片
		 };
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request, response); 

 }
 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  //设置编码格式为utf-8
  request.setCharacterEncoding("utf-8");
  response.setCharacterEncoding("utf-8"); 
  //获取session,保存进度和上传结果,上传开始为nok,当为Ok表示上传完成
  HttpSession session=request.getSession();
  session.setAttribute("result", "nok");
  session.setAttribute("error", "");
  String error="";
  upFileName="";
  isAllowed=false;
  //给上传的文件设一个最大值,这里是不得超过100MB
  int maxSize=100*1024*1024;
  //创建工厂对象和文件上传对象
  DiskFileItemFactory factory=new DiskFileItemFactory();
  ServletFileUpload upload=new ServletFileUpload(factory);
  //创建上传监听器和设置监听器
  UploadListener listener=new UploadListener();
  session.setAttribute("LISTENER", listener);
  upload.setProgressListener(listener);  
  //上传路径
  String path = request.getSession().getServletContext().getRealPath("/upload");
  String requestPath = request.getSession().getServletContext().getContextPath()+"/upload";
  File dirFile =new File(path);     //System.out.println(request.getSession().getServletContext().getContextPath());
  //如果文件夹不存在则创建    
  if  (!dirFile .exists()  && !dirFile .isDirectory())      
  {         
    dirFile .mkdir();    
  }    
  //根据日期创建文件夹,保存到对应日期的文件夹下
  Date date=new Date();
  SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
  String subDirName=sdf.format(date);
  File subDirFile=new File(path+"/"+subDirName);
  if  (!subDirFile .exists()  && !subDirFile .isDirectory())      
  {       
	  subDirFile .mkdir();    
  }   
  try {	 
   //解析上传请求
   List<FileItem> items=upload.parseRequest(request);   
   Iterator<FileItem> itr=items.iterator();   
   while(itr.hasNext()){	  
    FileItem item=(FileItem)itr.next();
    //判断是否为文件域   
    if(!item.isFormField()){     if(item.getName()!=null&&!item.getName().equals("")){
      //获取上传文件大小和文件名称
      long upFileSize=item.getSize();   
      String fileName=item.getName();
     
      //获取文件后缀名
      String[] splitName=fileName.split("\\.");
      String extName=splitName[splitName.length-1];
      //检查文件后缀名
      for(String allowed:allowedExtName)
      {
      	if(allowed.equalsIgnoreCase(extName))
      	{
      		isAllowed=true;
      	}     	
      }
      if(!isAllowed){
    	  error="上传文件格式不合法!";
    	  break;
      }
      if(upFileSize>maxSize){
       error="您上传的文件太大了,请选择不超过100MB的文件!";
       break;
      }  
      //此时文件暂存在服务器的内存中,构造临时对象
      File tempFile=new File(makeFileName(fileName));
     
      //指定文件上传服务器的目录及文件名称
      File file=new File(path+"/"+subDirName+"/",tempFile.getName());
     
      item.write(file);//第一种写文件方法
      upFileName=requestPath+"/"+subDirName+"/"+tempFile.getName();
  if(upFileName.equals("")){
	  error="没选择上传文件!";
  }
  System.out.println(upFileName);
      /*//构造输入流读文件 第二种写文件方法
      InputStream is=item.getInputStream();
      int length=0;
      byte[] by=new byte[1024];
      
      FileOutputStream fos=new FileOutputStream(file);
      
      while((length=is.read(by))!=-1){
       fos.write(by, 0, length);
       //Thread.sleep(10);
      }
      fos.close();
      //Thread.sleep(1000);*/
     }else{
      error="没选择上传文件!";
     }
    }
   }    
  } catch (Exception e) {
   e.printStackTrace();
   error="上传文件出现错误:"+e.getMessage();
  }
  if(!error.equals("")){ 
	  System.out.println(error);
   session.setAttribute("error", error);
  }else{  
	
   session.setAttribute("result", "OK"); 
   session.setAttribute("filename",upFileName);
  }
 }
 /**
  * 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
  * @param filename 原文件名
  * @return 生成的唯一文件名
  */
 private String makeFileName(String filename){ 
     
     return UUID.randomUUID().toString() + "_" + filename;
   } 
}

其中需要引入commons-fileupload-1.3.1.jar,commons-io-2.4.jar
上传过程中,我们需要实时获取上传进度等信息,引入的库里为我们添加了一个ProgressListener接口,我们再写一个类实现这个接口,上面类中添加该接口

//创建工厂对象和文件上传对象
  DiskFileItemFactory factory=new DiskFileItemFactory();
  ServletFileUpload upload=new ServletFileUpload(factory);
  //创建上传监听器和设置监听器
  UploadListener listener=new UploadListener();
  session.setAttribute("LISTENER", listener);
  upload.setProgressListener(listener);

下面是这个监听类的具体实现代码

package util.upload;

import org.apache.commons.fileupload.ProgressListener;

public class UploadListener implements ProgressListener{

	private volatile long 
	bytesRead = 0L,//上传的字节数
	contentLength = 0L,//总字节数
	item = 0L; 
	 public UploadListener() 
	    {
	    	super();
	    }
	 
	 @Override
	 public void update(long aBytesRead, long aContentLength, int anItem) {
	 	
	 	bytesRead = aBytesRead;
	     contentLength = aContentLength;
	     item = anItem;
	 }
	 public long getBytesRead() 
	 {
	     return bytesRead;
	 }
	 public long getContentLength() 
	 {
	     return contentLength;
	 }

	 public long getItem() 
	 {
	     return item;
	 }
}

现在能获取上传进度等信息了,但还需要一个servlet返回给前端,下面实现

package util.upload;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.ProgressListener;

import com.google.gson.Gson;
/**
 获取上传进度,上传路径,错误,上传结果等信息
 */

public class GetProgressServlet extends HttpServlet{

 private static final long serialVersionUID = -3596466520775012991L;

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request, response);
 }

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	  request.setCharacterEncoding("utf-8");
	  response.setCharacterEncoding("utf-8");
	  UploadListener listener= null;
	  HttpSession session = request.getSession();
	  String error=(String) session.getAttribute("error");
	  String result= (String) session.getAttribute("result");
	  String fileName=(String) session.getAttribute("filename");
	  PrintWriter out = response.getWriter();
	  long bytesRead = 0,contentLength = 0; 
	  if (session != null)
		{
			listener = (UploadListener)session.getAttribute("LISTENER");
			
			if (listener == null)
			{
				return;
			}
			else
			{				
		    	bytesRead = listener.getBytesRead();//上传的字节数
				contentLength = listener.getContentLength();//总字节数
				
			}
			//自己定义的返回格式
			String rp=bytesRead+","
					+contentLength+","
					+error+","
					+result+","
					+fileName;
		
			//System.out.println(rp);
			out.print(rp);
			/*		//返回json格式数据
			Map<String,Object> map=new HashMap<String,Object>();
			map.put("bytesRead", bytesRead);
			map.put("contentLength", contentLength);
			map.put("error", error);
			map.put("result", result);
			map.put("fileName", fileName);
			Gson gson=new Gson();
			String json=gson.toJson(map);
			out.print(json);*/
			out.flush();
			out.close();	
		}
 }
}

后台上传的功能代码写完了,下面实现上传的前端,首先是html

<!DOCTYPE html>
	<html>
    <head>
        <meta charset="utf-8" />
       	<script type="text/javascript" src="js/upfile.js" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="css/upfile.css">
    </head>
    <body >
        <a href="javascript:addOne()">添加</a>
        <div id="target">
            <input type="file" id="file" name="file" onchange="addfile(event)" multiple/>
        </div>
		<span id="test">0</span>
    </body>	
</html>

界面比较简单,就一个添加的a标签,负责上传的input隐藏起来
css文件主要渲染的上传进度的显示

            #file {
                display: none;
            }
            .pro{
            	width:500px;
            }
            .pborder {
                
                position: relative;
                width: 500px; /* 宽度 */
                border: 1px solid #B1D632;
                padding: 1px;
            }
            
            .drawpro {
                width: 0px;
                display: block;
                position: relative;
                background: #B1D632;
                color: #333333;
                height: 20px; /* 高度 */
                line-height: 20px; /* 必须和高度一致,文本才能垂直居中 */
            }
            
            .pspan {
                position: absolute;
                width: 500px;
                text-align: center;
                font-weight: bold;
            }

接着是前端的重点,js文件

//显示上传信息的html
var upfile_html = '<div class="pborder"><div class="drawpro">'
		+ '<span class="pspan">0%</span></div></div><span name="path"></span><img src="common/upload/images/del.png" style="float:right" width="20" height="20" name="del" οnclick=abortUpload(this)>';

var targetDIV_id = "target";//显示上传文件的目标div的ID
var httpXML = null;//发送上传请求的XMLHttpRequest对象
var httpProgress = null;//发送请求进度信息的XMLHttpRequest对象
var oldFileList = new Array();//修改时保存已有附件信息的列表
var uplist = new Array();//保存上传文件的列表
var f_input;//上传文件的input对象
var flag = true;//是否可以上传下一个文件标志
var uurl = "Upload";//上传文件的请求url
var gurl = "getProgress";//获取上传进度信息的url
var cancelFlag = 0;//取消标志
var timer, waittimer;//定时器
var nowID = 0;//正在上传文件的id
var ID = 0;//队列中最后一个文件的id

/**
 * 文件对象
 */
function UploadFile(id, file) {
	this.id = id;
	this.file = file;
	this.state = 0;
	this.path = "";
}
/**
 * 初始化的方法
 */
window.onload = function init() {
	f_input = document.getElementById("file");
	var tdiv = document.getElementById(targetDIV_id);

	var oldspan = tdiv.getElementsByTagName("SPAN");

	for ( var i = 0; i < oldspan.length; i++) {
		oldFileList.push(oldspan[i].getAttribute("name"));
	}
}

/**
 * 选择一个文件上传
 */
function addOne() {
	f_input.value = null;
	f_input.click();
}

/**
 * 选中文件后将文件对象添加到队列,开始上传
 * 
 */
function addfile(evt) {
	var f = f_input.files[0];
	if (f != undefined) {
		var uf = new UploadFile(ID, f);
		uplist.push(uf);
		var div = document.createElement("DIV");
		div.setAttribute("id", "pro" + (ID));
		div.setAttribute("class", "pro");
		div.innerHTML = upfile_html;
		var targetDiv = document.getElementById(targetDIV_id);
		targetDiv.appendChild(div);
		div.getElementsByTagName("SPAN")[1].innerHTML = "文件名:"
				+ uplist[ID].file.name;
		waittimer = setInterval("upload()", 1000);
		ID++;
	}
}
/**
 * 将队列中的文件上传
 */
function upload() {

	if (flag == true) {

		if (uplist.length > 0) {

			var uf;
			for ( var i = 0; i < uplist.length; i++) {
				if (uplist[i].state == 0) {
					uf = uplist[i];
					uplist[i].state = 1;
					break;
				}
			}

			if (uf != undefined & uf != null) {
				flag = false;
				if (window.XMLHttpRequest) {
					httpUP = new XMLHttpRequest();
				} else if (window.ActiveXObject) {
					httpUP = new ActiveXObject("Microsoft.XMLHTTP");
				}
				var formData = new FormData();
				formData.append("file", uf.file);
				httpUP.open("POST", uurl, true);
			  httpUP.upload.addEventListener('progress', uploadProgress, false);
				httpUP.send(formData);
				nowID = uf.id;
				timer = setInterval("getP()", 50);
			}
		}
	}
}

/**
 * 获取上传进度等信息
 */
function getP() {
	if (window.XMLHttpRequest) {
		httpProgress = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		httpProgress = new ActiveXObject("Microsoft.XMLHTTP");
	}
	httpProgress.onreadystatechange = onProgress;
	httpProgress.open("post", gurl, true);
	httpProgress.setRequestHeader("Content-type",
			"application/x-www-form-urlencoded");
	httpProgress.send("&timeStamp=" + (new Date()).getTime());
}

/**
 * 处理返回的上传信息,显示到界面
 */
function onProgress() {
	if (httpProgress.readyState == 4 && httpProgress.status == 200) {
		result = httpProgress.responseText;
		var result = result.replace(/(^\s*)|(\s*$)/g, "");
		var res = result.split(",");
		var now = parseInt(res[0]);
		var all = parseInt(res[1]);
		var err = res[2];
		var state = res[3];
		var path = res[4];
		var per = (now / all * 100).toFixed(2);
		var prodiv = document.getElementById("pro" + nowID);

		if (prodiv != null & prodiv != undefined) {
			if (err != "" & err != null & err.length > 0) {
				window.clearInterval(timer);
				if (cancelFlag == 1) {
					err = "上传终止";
					cancelFlag = 0;
				}
				prodiv.getElementsByTagName("DIV")[0].style.display = "none";
				prodiv.getElementsByTagName("SPAN")[1].innerHTML = err;
				httpUP.abort();
				flag = true;
				uplist[nowID].state = 3;
				return;
			}
			if (state == "OK") {
				prodiv.getElementsByTagName("DIV")[0].style.display = "none";
				var tmpf = uplist[nowID].file;
				prodiv.getElementsByTagName("SPAN")[1].innerHTML = "文件名:"
						+ tmpf.name;
				window.clearInterval(timer);
				flag = true;
				uplist[nowID].state = 2;
				uplist[nowID].path = path;
				return;
			}
			prodiv.getElementsByTagName("DIV")[1].style.width = per * 5 + "px";
			prodiv.getElementsByTagName("SPAN")[0].innerHTML = per + "%";
			
		}
	}
}

/**
 * 取消上传的方法
 */
function abortUpload(obj) {
	var idStr = obj.parentNode.id;
	var id = idStr.slice(3);
	if (uplist[id].state == 1) {
		httpUP.abort();
		flag = true;
		cancelFlag = 1;
	} else {
		uplist[id].state = 3;
	}
	document.getElementById(idStr).remove();

}
/**
 * 获取上传文件的路径
 * @returns 格式化后字符串
 */
function getFileListStr() {
	
	var str = "";
	if (oldFileList.length > 0) {
		for ( var i = 0; i < oldFileList.length; i++) {
			if (oldFileList[i] != null & oldFileList[i] != ""
					& oldFileList[i] != undefined) {
				str = str + oldFileList[i] + ",";
			}

		}
	}
	for ( var i = 0; i < uplist.length; i++) {
		var f = uplist[i];
		if (f.state == 2) {
			str = str + f.path + ",";
		}
	}
	return str;
}
/**
 * 移除修改时已有的旧附件
 * 
 */
function removeOld(btn) {
	var num = btn.getAttribute("name");
	oldFileList[num - 1] = null;
	btn.parentNode.remove();
}
   function uploadProgress(e) {
            	if (e.lengthComputable) {
            		var iBytesUploaded = e.loaded;
                    var iBytesTotal = e.total;
                    document.getElementById("test").innerHTML=iBytesUploaded+"/"+iBytesTotal;
            	}
            }

使用ajax发送上传文件,获取上传进度,结果等信息。
使用的html5的file API,所以必须ie9以上的才可以兼容,火狐还有个问题,ajax请求不立即返回,直到所有ajax请求都发送完了,才都返回同一个结果,这就导致上传进度不显示。不过上传进度信息也可以使用html5的file api获取,其中加了一点代码,页面下面test的div里的数值就是在前端获取到的进度。

上传的都实现完了,接着是处理上传后的临时文件,因为使用的uuid命名文件,所以文件会生成很多,没用的需要定时处理。使用ServletContextListener:
在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。

当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法。
利用其特性,实现定时删除临时文件的功能,代码如下:

package util.upload;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
/**  
 * 时间监听器  
 *   
 *  
 */  
public class TempFileListener implements ServletContextListener {  
    private Timer timer;  
    private SystemTaskTest systemTask;  
    private static String every_time_run;  
    static {  
        Properties prop = new Properties();  
        InputStream inStrem = TempFileManager.class.getClassLoader()  
                .getResourceAsStream("tempfile.properties");  
        try {  
            prop.load(inStrem);  
            System.out.println(inStrem);
            every_time_run = prop.getProperty("every_time_run");  
  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                inStrem.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    // 监听器初始方法  
    public void contextInitialized(ServletContextEvent sce) {  
  
        timer = new Timer();  
        systemTask = new SystemTaskTest(sce.getServletContext()  
                .getRealPath("/"), sce.getServletContext());  
        try {  
            System.out.println("定时器已启动");
            // 监听器获取网站的根目录  
            String path = sce.getServletContext().getRealPath("/");  
            Long time = Long.parseLong(every_time_run) * 1000;// 循环执行的时间  
            System.out.println("time" + time);   
            // 第一个参数是要运行的代码,第二个参数是从什么时候开始运行,第三个参数是每隔多久在运行一次。重复执行  
            timer.schedule(systemTask, 10000, time);  
            System.out.println("已经添加任务调度表");
        } catch (Exception e) {  
            e.printStackTrace();
        }  
    }  
  
    public void contextDestroyed(ServletContextEvent sce) {  
        try {  
            timer.cancel();  
        } catch (Exception e) {  
        }  
    }  
}  
  
/**  
 * 时间任务器  
 * 
 */  
class SystemTaskTest extends TimerTask {  
    private ServletContext context;  
    private String path;  
    public SystemTaskTest(String path, ServletContext context) {  
        this.path = path;  
        this.context = context;  
    }  
  
    /**  
     * 把要定时执行的任务就在run中  
     */  
    public void run() {   
        TempFileManager etf;     
        try {  
           
            System.out.println("开始执行任务!");
            // 需要执行的代码  
            System.out.println(new Date().toLocaleString());  

            etf = new TempFileManager(path);  
            etf.run();        
           
            System.out.println("指定任务执行完成!");
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  

上面只是监听器,负责定时调用删除临时文件的方法,具体实现是下面的类

package util.upload;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;
  
  
/**  
 * 删除服务器上的文件  
 * 
 */  
 
public class TempFileManager implements Runnable {  
    private String path;//路径  
  
    private static String RETENTION_TIME = "1440";// 文件保存的时间  一天单位分
    static {  
        Properties prop = new Properties();  
        InputStream inStrem = TempFileManager.class.getClassLoader()  
                .getResourceAsStream("execl.properties");  
        try {  
            prop.load(inStrem);  
            RETENTION_TIME = prop.getProperty("file_retention_time");  
  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                inStrem.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    /**  
     * 构造函数。初始化参数  
     * @param path  
     */  
    public TempFileManager(String path) {  
        this.path = path;  
       
    }  
    /**  
     * 把线程要执行的代码放在run()中  
     */  
    public void run() {  
        System.out.println("文件管理开始=========");  
        path = path + "upload";  
        System.out.println("文件管理路径===" + path);  
        File file = new File(path);  
        deletefiles(file);  
    }  
  
    /**  
     * 批量删除文件  
     *   
     * @param folder  
     */  
    public void deletefiles(File folder) { 
	if(folder.isDirectory()){
	    
        File[] files = folder.listFiles();
        if(files.length<=0){
            if(!folder.getAbsolutePath().equalsIgnoreCase(path)){
        	if(canDeleteFile(folder)){
        	    if (folder.delete()) {  
                    System.out.println("文件夹" + folder.getName() + "删除成功!");  
        	    } else {  
                    System.out.println("文件夹" + folder.getName()  
                            + "删除失败!此文件夹内的文件可能正在被使用");  
        	    }  
        	}
            }
        }
        for (int i = 0; i < files.length; i++) {  
            
            if(files[i].isDirectory())
        	{
        	deletefiles(files[i]);
        	}else{
        	    deleteFile(files[i]); 
        	}
            
        }  
	}
    }  
  
    /**  
     * 删除文件  
     *   
     * @param file  
     */  
    private void deleteFile(File file) {  
        try {  
            if (file.isFile()) {  
                // 删除符合条件的文件  
                if (canDeleteFile(file)) {  
                    if (file.delete()) {  
                        System.out.println("文件" + file.getName() + "删除成功!");  
                    } else {  
                        System.out.println("文件" + file.getName()  
                                + "删除失败!此文件可能正在被使用");  
                    }  
                } else {  
  
                }  
            } else {  
                System.out.println("没有可以删除的文件了");  
            }  
  
        } catch (Exception e) {  
            System.out.println("删除文件失败========");  
            e.printStackTrace();  
        }  
    }  
  
    /**  
     * 判断文件是否能够被删除  
     */  
    private boolean canDeleteFile(File file) {  
        Date fileDate = getfileDate(file);  
        Date date = new Date();  
        long time = (date.getTime() - fileDate.getTime()) / 1000 / 60  
                - Integer.parseInt(RETENTION_TIME);// 当前时间与文件间隔的分钟  
//        System.out.println("time=="+time);
        if (time > 0) {  
            return true;  
        } else {  
            return false;  
        }  
  
    }  
  
    /**  
     * 获取文件最后的修改时间  
     *   
     * @param file  
     * @return  
     */  
    private Date getfileDate(File file) {  
        long modifiedTime = file.lastModified();  
        Date d = new Date(modifiedTime);  
        return d;  
    }  

}  

判断文件是否超时,超时就自动删除,并且能自动删除文件夹。时时保持上传临时文件夹下干干净净,处女座最爱。。。
还有个配置文件,代码里能看到使用了那些参数,就不贴了,功能很简单,但也做了很久,搜了很多资料,感谢互联网上的各位分享知识的大神,没有他们,就没有这一切。再次感谢各位,虽然忘了看的哪些大神的文章做出来的了。。。如有不对,请指出,谢谢阅读。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值