ajax+servlet实现向服务端上传文件

本文介绍了一种通过浏览器分段读取并上传大文件的方法,利用JavaScript实现文件的分块读取,通过AJAX进行上传。同时,服务器端采用Java Servlet处理上传的数据,包括文件的接收与保存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

客户端代码:

<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);
}


}

以上代码我已经做过一遍,可实现文件上传,如有问题,欢迎提问。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值