客户端代码:
<html>
<head>maicaijian</head>
<body>hello world</body>
<!--这里文件上传实例-->
<form name="input" action="/dinner/Load" method="post">
//action的服务URL改成你自己的
<input type="submit" value="Submit">
<input type="file" name="pic" accept=".jpg,.png,.txt">
</form>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">分段读取文件:</div>
<div class="panel-body">
<input type="file" id="file" />
<blockquote style="word-break:break-all;"></blockquote>
</div>
</div>
</div>
<script>/*
* 分段读取文件为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//dinner/Load', 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>
<hr/>
<p>i am coming</p>
</html>
服务器端的代码:
public class Load extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Load() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try {
//获取客户端传过来图片的二进制流
InputStream stream = request.getInputStream() ;
//以当前时间戳为图片命名
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String strCurrentTime = df.format(new Date()) ;
String imagePath = "C://ServerImage/" + strCurrentTime+".txt"; //这里的文件格式可以自行修改,如.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 ;
//read the temp file
RandomAccessFile random = new RandomAccessFile(imagePath, "r") ;
//read line2 to find the name of the upload file.
int second = 1 ;
String secondLine = null ;
while(second <=2)
{
secondLine = random.readLine();
second++ ;
}
//get the last location of the dir char.'\\'
int position = secondLine.lastIndexOf('\\') ;
//get the name of the upload file.
String fileName = secondLine.substring(position+1, secondLine.length()-1) ;
//relocate to the head of file
random.seek(0);
//get the location of the char.'Enter' in Line4.
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") ;
//locate the end position of the content.Count backwards 6 lines
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++ ;
}
}
//locate to the begin of content.Count for 4 lines's end position.
random.seek(forthEndPosition);
long startPoint = random.getFilePointer() ;
//read the real content and write it to the realFile.
while(startPoint < endPosition-1)
{
n = random.readByte() ;
random2.write(n);
startPoint = random.getFilePointer() ;
}
random.close();
random2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
以上代码我已经做过一遍,可实现文件上传,如有问题,欢迎提问。