大数据量查询结果的文本导出

FileOutputStream fo = null;
 BufferedReader in = null;
 FileOutputStream f = null;
 ZipOutputStream zipout = null;
 FileInputStream inStream = null;
 ServletOutputStream outStream = null;
 
 HttpServletResponse response = request.getResponse();
 try {
 response.setContentType("text/plain;charset=GB2312");
 if (export.equals("txt")) {
 response.setHeader("Content-disposition",
 "attachment; filename="
 + new String("Query".getBytes("UTF-8"),
 "iso8859-1") + ".zip"); //导出zip压缩文件
 } else {
 response.setHeader("Content-disposition",
 "attachment; filename="
 + new String("Query".getBytes("UTF-8"),
 "iso8859-1") + ".zip");
 }
 outStream = response.getOutputStream();
 
 CheckedOutputStream ch = new CheckedOutputStream(outStream,
 new CRC32()); 
 zipout = new ZipOutputStream(new BufferedOutputStream(ch)); //把数据经过压缩直接写到response里面,避免中间文件生成,提高效率
 
 if (export.equals("txt")) { //压缩包文件格式
 zipout.putNextEntry(new ZipEntry("Query.txt")); 
 }else{
 zipout.putNextEntry(new ZipEntry("Query.xls"));
 }
 
 int pageSize = endIndex > 100000 ? 100000 : endIndex;
 if (endIndex == 1) {
 endIndex = 2;
 } 
 for (int i = startIndex; i < endIndex; i += pageSize) { //对于大数据量的导出,采取分批查询的方式,这里每次查询取100000条记录
 paraMap.put("startIndex", i);
 paraMap.put("endIndex", i + pageSize - 1);
 doExport(paraMap, zipout); //在这个函数中把从数据库查询出来的数据直接写到zipoutStream输出流中,
 zipout.flush();
 outStream.flush(); //每100000条就把response缓冲区数据推送到客户端,response可以使用flush将数据库缓存到客户端,减少服务器端内存压力,
 }
 zipout.close();
 outStream.close(); //关闭response
 } catch (Exception e) {
 // e.printStackTrace();
 } finally {
 }

 

对于大数据量导出,主要采取几种方案:

1.分批查询数据库,如果数据量上百万,如果一次性读出来,会严重影响服务器性能,增加服务器内存压力,分批导出,分批处理,可以使内存使用比较平稳,不会一次性占用大量内存。

2.压缩处理,导出的数据经过压缩直接写到response里面,一般的文本压缩率非常高,压缩后的文件会小很多,而且也不要先把数据写到临时文件,再做压缩,直接压缩写到response即可。

doExport(paraMap, zipout); //在这个函数中把从数据库查询出来的数据直接写到zipoutStream输出流中,这里往zipout写要这样,zipout.write("hello".getBytes());,要以字节流写到zipoutstream中。

3. zipout.flush();
    outStream.flush(); //每100000条就把response缓冲区数据推送到客户端,response可以使用flush将数据库缓存到客户端,减少服务器端内存压力,

    分批查询数据库把数据写到response时要用flush,将数据缓冲到客户端,这样有两个好处;一是可以把数据推送到客户端,减少服务器端内存压力,避免影响服务器性能;二是如果本次请求需要查询出几百万的数据,如果不flush,那么服务器端的本次请求仍然会去数据库查询这几百万的数据,这会严重的影响服务器端的性能,从数据库查询出这几百万的数据,而客户端已经取消了本次请求,这样就不能再让服务器继续处理下去,使用flush可以检测客户端的请求是否还存在,不存在会抛出异常,用flush可以捕获到该异常及时中止本次请求,不再去查询数据库,不再处理本次请求。

你可能感兴趣的:(F#)