通过ajax、servlet实现图片的上传功能
经测试可行,本人上传的地址是要在C盘的目录下建一个"Image"文件夹(当然可以自行创建)
jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <!--这里文件上传实例--> <div class="container"> <div class="panel-heading">分段读取文件:</div> <div class="panel-body"> <input type="file" id="file" /> </div> </div> </body> <script type="text/javascript"> /* * 分段读取文件为blob ,并使用ajax上传到服务器 * 分段上传exe文件会抛出异常 */ var fileBox = document.getElementById('file'); file.onchange = function() { // 获取文件对象 var file = this.files[0]; var reader = new FileReader(); var step = 1024 * 1024; var total = file.size; var cuLoaded = 0; console.info("文件大小:" + file.size); var startTime = new Date(); // 读取一段成功 reader.onload = function(e) { // 处理读取的结果 var loaded = e.loaded; // 将分段数据上传到服务器 uploadFile(reader.result, cuLoaded, function() { console.info('loaded:' + cuLoaded + 'current:' + loaded); // 如果没有读完,继续 cuLoaded += loaded; if (cuLoaded < total) { readBlob(cuLoaded); } else { console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000); cuLoaded = total; } }); } // 指定开始位置,分块读取文件 function readBlob(start) { // 指定开始位置和结束位置读取文件 // console.info('start:' + start); var blob = file.slice(start, start + step); reader.readAsArrayBuffer(blob); } // 开始读取 readBlob(0); // 关键代码上传到服务器 function uploadFile(result, startIndex, onSuccess) { var blob = new Blob([ result ]); // 提交到服务器 var fd = new FormData(); fd.append('file', blob); fd.append('filename', file.name); fd.append('loaded', startIndex); var xhr = new XMLHttpRequest(); xhr.open('post', 'http://localhost:8080//uploadtwo/UploadServlet', true); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { // var data = eval('(' + xhr.responseText + ')'); console.info(xhr.responseText); if (onSuccess) onSuccess(); } } // 开始发送 xhr.send(fd); } } </script> </html>
后端UploadServlet:
package com.servlet; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/UploadServlet") public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // 获取客户端传过来图片的二进制流 InputStream stream = request.getInputStream(); // 以当前时间戳为图片命名 SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String strCurrentTime = df.format(new Date()); //最终文件存储位置 String imagePath = "C://Image/" + strCurrentTime + ".png"; // 这里的文件格式可以自行修改,如.jpg FileOutputStream fos = new FileOutputStream(imagePath); byte[] bbuf = new byte[32]; int hasRead = 0; while ((hasRead = stream.read(bbuf)) > 0) { fos.write(bbuf, 0, hasRead); // 将文件写入服务器的硬盘上 } fos.close(); stream.close(); /* * 但是需要注意,采用这种原始的方式写入文件时,你会发现被写入的文件内容前4行并非是读取文件的真正内容, * 从第四行开始才是正文数据。第二行是文件路径以及名称。所以通常的做法是,先将文件写入临时文件中,然后 * 再采用RandomAccessFile读取临时文件的第四行以后部分。写入到目标文件中。 */ Byte n; // 读取临时文件 RandomAccessFile random = new RandomAccessFile(imagePath, "r"); int second = 1; String secondLine = null; while (second <= 2) { secondLine = random.readLine(); second++; } int position = secondLine.lastIndexOf('\\'); // 获取上传文件的名称 String fileName = secondLine.substring(position + 1, secondLine.length() - 1); random.seek(0); long forthEndPosition = 0; int forth = 1; while ((n = random.readByte()) != -1 && (forth <= 4)) { if (n == '\n') { forthEndPosition = random.getFilePointer(); forth++; } } RandomAccessFile random2 = new RandomAccessFile(imagePath, "rw"); random.seek(random.length()); long endPosition = random.getFilePointer(); long mark = endPosition; int j = 1; while ((mark >= 0) && (j <= 6)) { mark--; random.seek(mark); n = random.readByte(); if (n == '\n') { endPosition = random.getFilePointer(); j++; } } random.seek(forthEndPosition); long startPoint = random.getFilePointer(); while (startPoint < endPosition - 1) { n = random.readByte(); random2.write(n); startPoint = random.getFilePointer(); } random.close(); random2.close(); } catch (Exception e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
到这里就结束了,试一下吧!!