文件上传功能在开发当中经常用得到。在以往,一般会将文件保存在服务器上。这个时候要考虑保存文件的唯一性和高效性。
也就是说保存文件要给文件唯一的命名,防止文件名冲突导致信息错误。常采用的方法为时间戳和UUID,两种办法都可以。时间戳可能会重复,一般情况下不会重复的!!!
时间戳:
long id = Date().getTime();
UUID(身份唯一标识)
UUID uuid = UUID.randomUUID();
高效性就是对于文件的位置的存放比如说把 同一天上传的文件放到一个文件夹,一年的放到一个文件夹这样按照时间来区分开,这样在读取的时候效率就会好一点。
那么使用java如何实现文件上传呢?
html:
目前h5提供了一个方法是FormData 属性可以直接将文件转化成流发送到后台,这样上传就非常简单了。
<body>
<form id="uploadForm" enctype="multipart/form-data" method="post">
<p>指定文件名:<input type="text" name="fileId" i></p>
<p>上传文件:<input type="file" name="filename"></p>
<button id="upload">上传</button>
</form>
</body>
<script src="jquery-3.2.1.min.js"></script>
<script>
$("#upload").on('click',function () {
var formData = new FormData($("#uploadForm")[0]);
$.ajax({
url:"/uploadServlet",
type:"POST",
data:formData,
async: false,
cache: false,
contentType: false,
processData: false,
success:function (res) {
alert(res);
},
error:function (res) {
alert(res);
}
})
});
</script>
后台java接收流转化为文件,要引入两个jar包
commons-io-2.0.1.jar
commons-fileupload-1.2.2.jar
代码如下:
//获得时间戳
long id = new Date().getTime();
//获得存错的位置
String savePath = getServletContext().getRealPath("file/");
//使用apache组件上传文件
//实例化一个diskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//实例化文件解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//解决乱码问题
upload.setHeaderEncoding("utf-8");
/*
* //监听上传的进度
fileUpload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int arg2) {
System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
}
});
* */
//3、判断提交上来的数据是否是上传表单的数据
if (!upload.isMultipartContent(request)) {
//按照传统方式获取数据
return;
}
/* //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
upload.setFileSizeMax(1024*1024);
//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
upload.setSizeMax(1024*1024*10);*/
//使用servletFileUpload解析文件
List<FileItem> list = null;
int row = 0;
try {
list = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
//遍历FileItem集合
Iterator<FileItem>itemIterator = list.iterator();
while (itemIterator.hasNext()){
FileItem item = itemIterator.next();
String fileName = "";
if(!item.isFormField()){
//文件项目
if(item.getName() != null && !item.getName().isEmpty()){
//获得文件的名字
String name = item.getName();
//获取文件后缀名前面的.的下标
int index = name.lastIndexOf('.');
//获取文件后缀名
String suffix = name.substring(index);
//使用时间戳为存储的新的文件命名
fileName = String.format("%d%s",id,suffix);
//获得文件的存储路径
String fileUrl = String.format("%s\\%s",savePath,fileName);
File file = new File(fileUrl);
try {
item.write(file);
String path = request.getContextPath();
String basePath = request.getScheme() +"://" + request.getServerName() + ":" + request
.getServerPort() + path;
String dbUrl = String.format("%s/file/%s",basePath,fileName);
row = FileDAO.add(dbUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}else {
//普通字段
String fieldName = item.getFieldName();//字段名称
String fieldNameValue = item.getString();//普通字段的值
System.out.println(fieldName+":"+fieldNameValue);
}
}
PrintWriter out = response.getWriter();
if(row == 0){
out.write("error");
}else {
out.write("success");
}
out.flush();
out.close();
}
更多的设置还有很多,比如限制文件的大小等。是可以通过后台设置的!
文件下载就更简单了 只需要在a标签中加入地址,并且给一个属性down即可