經測試可行,本人上傳的地址是要在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); } }
到這里就結束了,試一下吧!!