博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
文件上传和下载(可批量上传)——基础(一)
阅读量:5321 次
发布时间:2019-06-14

本文共 21948 字,大约阅读时间需要 73 分钟。

出自:http://www.cnblogs.com/xdp-gacl/p/4200090.html

  此处为底层的上传和下载的实现,没有用其他框架。如Spring

  对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参 数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件。这个common-fileupload上 传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,struts上传的功能就是基于这个实现的。 common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。

一、开发环境搭建

  创建一个FileUploadAndDownLoad项目,加入Apache的commons-fileupload文件上传组件的相关Jar包,如下图所示:

  

二、实现文件上传

2.1、文件上传页面和消息提示页面

  upload.jsp页面的代码如下:

1 <%-- 2   Created by IntelliJ IDEA. 3   User: OnlyOne 4   Date: 2016/3/3 5   Time: 14:14 6   To change this template use File | Settings | File Templates. 7 --%> 8 <%@ page language="java" pageEncoding="UTF-8"%> 9 10 11 12     文件上传13 14 15 16 
17 上传用户:
18 上传文件1:
19 上传文件2:
20
21
22 23

 

  message.jsp的代码如下:

 

1 <%-- 2   Created by IntelliJ IDEA. 3   User: OnlyOne 4   Date: 2016/3/3 5   Time: 14:14 6   To change this template use File | Settings | File Templates. 7 --%> 8 <%@ page language="java" pageEncoding="UTF-8"%> 9 10 11 12     消息提示13 14 15 16     ${message}17 18 

 

2.2、处理文件上传的Servlet

  UploadFile的代码如下:

1 package file;  2   3 import org.apache.commons.fileupload.FileItem;  4 import org.apache.commons.fileupload.FileUploadException;  5 import org.apache.commons.fileupload.disk.DiskFileItemFactory;  6 import org.apache.commons.fileupload.servlet.ServletFileUpload;  7   8 import javax.servlet.ServletException;  9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.*; 13 import java.util.List; 14  15 /** 16  * Created by OnlyOne on 2016/3/3. 17  */ 18 public class UploadFile extends HttpServlet  { 19     /** 20      * 21      * @param req 22      * @param resp 23      * @throws ServletException 24      * @throws IOException 25      */ 26     @Override 27     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 28         /*//防止中文乱码,与页面字符集一致 29         req.setCharacterEncoding("UTF-8");*/ 30         //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全 31         String savePath = req.getServletContext().getRealPath("/WEB-INF/upload"); 32 //                            this.getServletContext().getRealPath("/WEB-INF/upload"); 33         //创建保存目录的文件 34         File saveFile = new File(savePath); 35         //判断保存目录文件是否存在,不存在则创建一个文件夹 36         if(!saveFile.exists()){ 37             System.out.println("文件目录创建中。。。"); 38             saveFile.mkdir(); 39         } 40         //消息提示 41         String message = ""; 42         //使用Apache文件上传组件处理文件上传步骤: 43         try { 44             //1、创建一个DiskFileItemFactory工厂 45             DiskFileItemFactory factory = new DiskFileItemFactory(); 46             //2.创建一个文件上传解析器 47             ServletFileUpload upload = new ServletFileUpload(factory); 48             //解决上传文件名的中文乱码 49             upload.setHeaderEncoding("UTF-8"); 50             //3.判断提交上来的数据是否是上传表单的数据 51             if(!ServletFileUpload.isMultipartContent(req)){ 52                 //按照传统方式获取数据 53                 return; 54             } 55             //4.使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List
集合, 56 // 每一个FileItem对应一个Form表单的输入项 57 List
list = upload.parseRequest(req); 58 for(FileItem item: list){ 59 //如果FileItem中封装的是普通输入项的数据 60 if(item.isFormField()){ 61 String name = item.getFieldName(); 62 //解决普通输入项的数据的中文乱码问题 63 String value = item.getString("UTF-8"); 64 // value = new String(value.getBytes("iso8859-1"),"UTF-8"); 65 System.out.println(name + "=" + value); 66 }else{
//如果fileitem中封装的是上传文件 67 //得到上传的文件名称 68 String fileName = item.getName(); 69 System.out.println("文件名是:"+ fileName); 70 if(fileName == null || fileName.trim().equals("")){ 71 continue; 72 } 73 /*注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的, 74 如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt*/ 75 //处理获取到的上传文件的文件名的路径部分,只保留文件名部分.如果传上来的文件名没有带路径,则lastIndexOf返回-1 76 fileName = fileName.substring(fileName.lastIndexOf("\\")+1); 77 //获取item中的上传输入流 78 BufferedInputStream bis = new BufferedInputStream(item.getInputStream()); 79 //创建一个文件输出流 80 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savePath + "\\" + fileName)); 81 //创建一个缓冲区 82 byte[] buffer = new byte[1024*8]; 83 //循环将缓冲输入流读入到缓冲区当中 84 while(true){ 85 //循环将缓冲输入流读入到缓冲区当中 86 int length = bis.read(buffer); 87 //判断是否读取到文件末尾 88 if(length == -1){ 89 break; 90 } 91 //使用BufferedOutputStream缓冲输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中 92 bos.write(buffer,0,length); 93 } 94 //关闭输入流 95 bis.close(); 96 //关闭输出流 97 bos.close(); 98 //删除处理文件上传时生成的临时文件 99 item.delete();100 message = "文件上传成功!";101 }102 }103 } catch (FileUploadException e) {104 message= "文件上传失败!";105 }106 req.setAttribute("message",message);107 req.getRequestDispatcher("/message.jsp").forward(req,resp);108 }109 110 @Override111 public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {112 doGet(req, resp);113 }114 }

 

 

 

  在Web.xml文件中注册UploadFile

UploadFile
file.UploadFile
UploadFile
/servlet/UploadFile

  运行效果如下:

   

  文件上传成功之后,上传的文件保存在了WEB-INF目录下的upload目录,如下图所示:

  

2.3、文件上传的细节

  上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的

  1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

  2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

  3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。

  4、要限制上传文件的最大值。

  5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

  针对上述提出的5点细节问题,我们来改进一下UploadFile_better,改进后的代码如下:

1 package file;  2   3 import org.apache.commons.fileupload.FileItem;  4 import org.apache.commons.fileupload.FileUploadBase;  5 import org.apache.commons.fileupload.FileUploadException;  6 import org.apache.commons.fileupload.ProgressListener;  7 import org.apache.commons.fileupload.disk.DiskFileItemFactory;  8 import org.apache.commons.fileupload.servlet.ServletFileUpload;  9  10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import java.io.*; 15 import java.util.List; 16  17 /** 18  * Created by OnlyOne on 2016/3/3. 19  */ 20 public class UploadFile_better extends HttpServlet  { 21     @Override 22     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 23         /*//防止中文乱码,与页面字符集一致 24         req.setCharacterEncoding("UTF-8");*/ 25         //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全 26         String savePath = req.getServletContext().getRealPath("/WEB-INF/upload"); 27 //                            this.getServletContext().getRealPath("/WEB-INF/upload"); 28         //上传时生成的临时文件保存目录 29         String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp"); 30         //创建保存目录的文件 31         File tempFile = new File(tempPath); 32         //判断保存目录文件是否存在,不存在则创建一个文件夹 33         if(!tempFile.exists()){ 34             System.out.println("文件目录创建中。。。"); 35             tempFile.mkdir(); 36         } 37         //消息提示 38         String message = ""; 39         //使用Apache文件上传组件处理文件上传步骤: 40         try { 41             //1、创建一个DiskFileItemFactory工厂 42             DiskFileItemFactory factory = new DiskFileItemFactory(); 43  44             //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。 45             //设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB 46             factory.setSizeThreshold(1024 * 100); 47  48             //2.创建一个文件上传解析器 49             ServletFileUpload upload = new ServletFileUpload(factory); 50  51             //监听文件上传进度 52             upload.setProgressListener(new ProgressListener() { 53                 @Override 54                 public void update(long pBytesRead, long pContentLength, int arg2) { 55                     System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead); 56                 } 57             }); 58  59             //解决上传文件名的中文乱码 60             upload.setHeaderEncoding("UTF-8"); 61  62             //3.判断提交上来的数据是否是上传表单的数据 63             if(!ServletFileUpload.isMultipartContent(req)){ 64                 //按照传统方式获取数据 65                 return; 66             } 67  68             //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB 69             upload.setFileSizeMax(1024*1024); 70             //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB 71             upload.setSizeMax(1024*1024*10); 72  73             //4.使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List
集合, 74 // 每一个FileItem对应一个Form表单的输入项 75 List
list = upload.parseRequest(req); 76 for(FileItem item: list){ 77 //如果FileItem中封装的是普通输入项的数据 78 if(item.isFormField()){ 79 String name = item.getFieldName(); 80 //解决普通输入项的数据的中文乱码问题 81 String value = item.getString("UTF-8"); 82 // value = new String(value.getBytes("iso8859-1"),"UTF-8"); 83 System.out.println(name + "=" + value); 84 }else{
//如果fileitem中封装的是上传文件 85 //得到上传的文件名称 86 String fileName = item.getName(); 87 System.out.println("文件名是:"+ fileName); 88 if(fileName == null || fileName.trim().equals("")){ 89 continue; 90 } 91 /*注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的, 92 如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt*/ 93 //处理获取到的上传文件的文件名的路径部分,只保留文件名部分.如果传上来的文件名没有带路径,则lastIndexOf返回-1 94 fileName = fileName.substring(fileName.lastIndexOf("\\")+1); 95 96 //得到上传文件的扩展名 97 String fileExtName = fileName.substring(fileName.lastIndexOf(".")+1); 98 //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法 99 System.out.println("上传的文件的扩展名是:"+fileExtName);100 101 //获取item中的上传输入流102 BufferedInputStream bis = new BufferedInputStream(item.getInputStream());103 104 //得到文件保存的名称105 String saveFilename = makeFileName(fileName);106 //得到文件的保存目录107 String realSavePath = makePath(saveFilename, savePath);108 109 //创建一个文件输出流110 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(realSavePath + "\\" + saveFilename));111 //创建一个缓冲区112 byte[] buffer = new byte[1024*8];113 //循环将缓冲输入流读入到缓冲区当中114 while(true){115 //循环将缓冲输入流读入到缓冲区当中116 int length = bis.read(buffer);117 //判断是否读取到文件末尾118 if(length == -1){119 break;120 }121 //使用BufferedOutputStream缓冲输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中122 bos.write(buffer,0,length);123 }124 //关闭输入流125 bis.close();126 //关闭输出流127 bos.close();128 //删除处理文件上传时生成的临时文件129 item.delete();130 message = "文件上传成功!";131 }132 }133 } catch (FileUploadBase.FileSizeLimitExceededException e) {134 message = "单个文件超出最大值!!!";135 e.printStackTrace();136 System.out.println("单个文件超出最大值!!!");137 }catch (FileUploadBase.SizeLimitExceededException e) {138 message = "上传文件的总的大小超出限制的最大值!!!";139 e.printStackTrace();140 System.out.println("上传文件的总的大小超出限制的最大值!!!");141 }catch (Exception e) {142 message= "文件上传失败!";143 e.printStackTrace();144 }145 System.out.println("执行跳转");146 req.setAttribute("message",message);147 req.getRequestDispatcher("/message.jsp").forward(req,resp);148 }149 150 @Override151 public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {152 doGet(req, resp);153 }154 155 /**156 * @Method: makeFileName157 * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称158 * @Anthor:OnlyOne159 * @param filename 文件的原始名称160 * @return uuid+"_"+文件的原始名称161 */162 private String makeFileName(String filename){ //2.jpg163 //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名164 return OrderIdBuilder.createOrderId().toString() + "_" + filename;165 }166 167 /**168 * 为防止一个目录下面出现太多文件,要使用hash算法打散存储169 * @Method: makePath170 * @Anthor:OnlyOne171 * @param filename 文件名,要根据文件名生成存储目录172 * @param savePath 文件存储路径173 * @return 新的存储目录174 */175 private String makePath(String filename,String savePath){176 //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址177 int hashcode = filename.hashCode();178 int dir1 = hashcode&0xf; //0--15179 int dir2 = (hashcode&0xf0)>>4; //0-15180 //构造新的保存目录181 String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5182 //File既可以代表文件也可以代表目录183 File file = new File(dir);184 //如果目录不存在185 if(!file.exists()){186 //创建目录187 file.mkdirs();188 }189 return dir;190 }191 }

 

 

  针对上述提出的5点小细节问题进行改进之后,我们的文件上传功能就算是做得比较完善了。

三、文件下载

3.1、列出提供下载的文件资源

  我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。

  ListFileServlet的代码如下:

1 package file; 2  3 import javax.servlet.ServletException; 4 import javax.servlet.http.HttpServlet; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import java.io.File; 8 import java.io.IOException; 9 import java.util.HashMap;10 import java.util.Map;11 12 /**13  * Created by OnlyOne on 2016/3/4.14  * @ClassName: ListFileServlet15  * @Description: 列出Web系统中所有下载文件16  *17  */18 public class ListFileServlet extends HttpServlet {19     @Override20     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {21         //获取上传文件的目录22         String uploadFilePath = req.getServletContext().getRealPath("/WEB-INF/upload");23         //存储要下载的文件名24         Map
fileNameMap = new HashMap
();25 //地鬼遍历filePath目录下的所有文件和目录,将文件的文件名存储到map集合中26 listfile(new File(uploadFilePath),fileNameMap);27 req.setAttribute("fileNameMap", fileNameMap);28 req.getRequestDispatcher("/listFile.jsp").forward(req, resp);29 }30 31 /**32 * Created by OnlyOne on 2016/3/4.33 * @Method: listfile34 * @Description: 递归遍历指定目录下的所有文件35 * @param file 即代表一个文件,也代表一个文件目录36 * @param map 存储文件名的Map集合37 */38 private void listfile(File file, Map
map){39 //如果file代表的不是一个文件,而是一个目录40 if(!file.isFile()){41 //列出该目录下的所有文件和目录42 File files[] = file.listFiles();43 //遍历files[]数组44 for(File f : files){45 //递归46 listfile(f,map);47 }48 }else{49 /**50 * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分51 file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi52 那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分53 */54 String realName = file.getName().substring(file.getName().indexOf("_")+1);55 //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复56 map.put(file.getName(), realName);57 }58 }59 60 @Override61 public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {62 doGet(req, resp);63 }64 }

 

 

  这里简单说一下ListFileServlet中listfile方法,listfile方法是用来列出目录下的所有文件的,listfile 方法内部用到了递归,在实际开发当中,我们肯定会在数据库创建一张表,里面会存储上传的文件名以及文件的具体存放目录,我们通过查询表就可以知道文件的具 体存放目录,是不需要用到递归操作的,这个例子是因为没有使用数据库存储上传的文件名和文件的具体存放位置,而上传文件的存放位置又使用了散列算法打散存 放,所以需要用到递归,在递归时,将获取到的文件名存放到从外面传递到listfile方法里面的Map集合当中,这样就可以保证所有的文件都存放在同一 个Map集合当中。

  在Web.xml文件中配置ListFileServlet

1     
2
ListFileServlet
3
file.ListFileServlet
4
5
6
ListFileServlet
7
/servlet/ListFileServlet
8

 

  展示下载文件的listfile.jsp页面如下:

1 <%-- 2   Created by IntelliJ IDEA. 3   User: OnlyOne 4   Date: 2016/3/4 5   Time: 10:49 6   To change this template use File | Settings | File Templates. 7 --%> 8 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 9 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>10 11 12 13     下载文件显示页面14 15 16 17 
18
19
20
21
22 ${me.value}
下载23
24
25 26

 

  访问ListFileServlet,就可以在listfile.jsp页面中显示提供给用户下载的文件资源,如下图所示:

  

3.2、实现文件下载

  编写一个用于处理文件下载的Servlet,DownLoadFile的代码如下:

1 package file; 2  3  4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import java.io.*; 9 import java.net.URLEncoder;10 11 /**12  * Created by OnlyOne on 2016/3/4.13  */14 public class DownLoadFile extends HttpServlet{15     @Override16     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {17         //得到要下载的文件名18         req.setCharacterEncoding("UTF-8");19         String fileName = req.getParameter("fileName");20 //        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");21         //上传的文件都是保存在/WEN-INF/upload目录党徽宗22         String fileSaveRootPath = req.getServletContext().getRealPath("/WEB-INF/upload");23         //铜鼓文件名找出文件的所在目录24         String path = findFileSavePathByFileName(fileName, fileSaveRootPath);25         //得到要下载的文件26         File file = new File(path + "//" + fileName);27         //如果文件不存在28         if(!file.exists()){29             req.setAttribute("message", "资源已被删除!");30             req.getRequestDispatcher("/message.jsp").forward(req, resp);31         }32         //处理文件名33         String realName = fileName.substring(fileName.indexOf("_")+1);34         //设置响应头,控制浏览器下载该文件35         resp.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(realName, "UTF-8"));36         //读取要下载的文件,保存到文件输入流37         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path + "\\" + fileName));38         //创建输出流39         BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());40         //创建一个缓冲区41         byte[] buffer = new byte[1024*8];42         //循环将缓冲输入流读入到缓冲区当中43         while(true){44             //循环将缓冲输入流读入到缓冲区当中45             int length = bis.read(buffer);46             //判断是否读取到文件末尾47             if(length == -1){48                 break;49             }50             //使用BufferedOutputStream缓冲输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中51             bos.write(buffer,0,length);52         }53         //关闭文件输入流54         bis.close();55         //刷新此输入流并强制写出所有缓冲的输出字节数56         bos.flush();57         //关闭文件输出流58         bos.close();59     }60 61     /**62      * Created by OnlyOne on 2016/3/4.63      * @Method: findFileSavePathByFileName64      * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径65      * @param filename 要下载的文件名66      * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录67      * @return 要下载的文件的存储目录68      */69     private String findFileSavePathByFileName(String filename,String saveRootPath){70         int hashcode = filename.hashCode();71         int dir1 = hashcode&0xf;  //0--1572         int dir2 = (hashcode&0xf0)>>4;  //0-1573         String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\574         File file = new File(dir);75         if(!file.exists()){76             //创建目录77             file.mkdirs();78         }79         return dir;80     }81 82     @Override83     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {84         doGet(req, resp);85     }86 }

 

 

  在Web.xml文件中配置DownLoadFile

1     
2
DownLoadFile
3
file.DownLoadFile
4
5
6
DownLoadFile
7
/servlet/DownLoadFile
8

 

  点击【下载】超链接,将请求提交到DownLoadServlet就行处理就可以实现文件下载了,运行效果如下图所示:

  

  从运行结果可以看到,我们的文件下载功能已经可以正常下载文件了。

  关于JavaWeb中的文件上传和下载功能的内容就这么多。

转载于:https://www.cnblogs.com/onlymate/p/5241864.html

你可能感兴趣的文章
[转]MySQL远程连接ERROR 2003 (HY000):Can't connect to MySQL server on'XXXXX'(111) 的问题
查看>>
[基础] 常见分布
查看>>
安装eclipse和CDT
查看>>
浅谈对象的序列化(Serialize)
查看>>
IIS 状态代码
查看>>
iOS 简单获取当前地理坐标
查看>>
第四周 兴趣问题清单
查看>>
279. Perfect Squares
查看>>
汇编学习笔记(2)-80x86寻址方式
查看>>
队列同步器详解
查看>>
Vim常用操作总结
查看>>
我的前端规范——HTML篇
查看>>
java操作MongoDB
查看>>
第三节:numpy之数组数学运算
查看>>
Discuz去掉标题上的powered by discuz!
查看>>
博客园的Markdown编辑器学习
查看>>
题目:小明学算术
查看>>
闭包的初步研究
查看>>
对async 函数的研究
查看>>
JAVA-初步认识-第九章-继承-子父类中的构造函数-子类的实例化过程
查看>>