关于BufferedWriter.write超过30W条数据写入过慢问题。
原创文章,转载请注明出处!
------------------------------------------------------------
今天接到一个项目需求变更,是关于从数据库查询到30W条数据放到一个List中,然后使用StringBuffer把List取出放入到StringBuffer中。最后使用 BufferedWriter.write(buffer.toString());添加到文件中,此时会消耗几个小时才能把数据存放到文件中。
项目源码:
public void generateCommonSMSFile(String localFilePath,String date) throws Exception{
try {
List smsList = getSingleDataSMS("03",date);
List listid = new ArrayList();
List subList = new ArrayList();
StringBuffer buffer = new StringBuffer("S|2|S0355||||");
buffer.append(smsList.size() + "|");
buffer.append("\r\n");
if(smsList != null && smsList.size() != 0) {
for(int i = 0;i < smsList.size();i++) {
OmsSingleDataDTO msdd = (OmsSingleDataDTO)smsList.get(i);
String transDate = msdd.getTransDate();
String leastDate = msdd.getLeastDate();
buffer.append(String.valueOf(i+1));
buffer.append("|");
buffer.append(msdd.getMobile());
buffer.append("|");
buffer.append(msdd.getCustNo());
buffer.append("|");
buffer.append(msdd.getAdvMemo1());
buffer.append("|");
buffer.append(CommonUtil.deleteZero(transDate.substring(5, 7))+"月"+CommonUtil.deleteZero(transDate.substring(8))+"日");
buffer.append("|");
buffer.append(msdd.getTransAmount());
buffer.append("|");
buffer.append(CommonUtil.deleteZero(leastDate.substring(4, 6))+"月"+CommonUtil.deleteZero(leastDate.substring(6))+"日");
buffer.append("|");
buffer.append("FQ"+msdd.getConsumeCode());
buffer.append("|");
buffer.append(msdd.getInstNum());
buffer.append("|");
buffer.append(msdd.getFirstAmount());
buffer.append("|");
buffer.append(msdd.getEachAmount());
buffer.append("|");
buffer.append(msdd.getTotalPoundage());
buffer.append("|");
buffer.append(msdd.getAdvMemo2());
buffer.append("|");
buffer.append("\r\n");
subList.add(msdd.getSeqId());
if((i+1)%5000==0){
listid.add(subList);
subList=new ArrayList();
}
}
listid.add(subList);
}
File file1 = FileUtils.createFile(localFilePath);
BufferedWriter bw = FileUtils.getWrite(file1);
bw.write(buffer.toString());
bw.close();
if(listid != null && listid.size() >= 1) {
for(int i=0;i<listid.size();i++) {
OMSLogger.info("普通消费类 - 第"+ (i+1) +"次运行开始");
long msBefore = System.currentTimeMillis();
updateMosSingleData((List)listid.get(i));
long msAfter = System.currentTimeMillis();
OMSLogger.info("普通消费类 - 第"+ (i+1) +"次运行结束,共耗时" + (msAfter - msBefore) + "毫秒");
}
}
} catch (Exception e) {
OMSLogger.error("生成单笔分期批量短信文件异常");
throw new Exception("生成单笔分期批量短信文件异常",e);
}
}
查询数据库,返回list供上面的数据写入文件的方法使用
private List getSingleDataSMS(String instFlag,String vdate) throws PafaDAOException {
List SmsList = new ArrayList();
List list = new ArrayList();
OmsSingleDataDTO msdd = null;
// list = executeSqlDao.queryForList("SELECT-SMS-SingleData-LIST",null);
HashMap map =new HashMap();
map.put("instFlag", instFlag);
map.put("vdate", vdate);
int total = 0;
total = ((Integer)executeSqlDao.queryForObject("SELECT-SMS-SingleData-COUNT", map)).intValue();
// 防止大于1万条时出错,循环处理
for(int i=0; i<total; i+=5000){
HashMap paramMap =new HashMap();
List rs = new ArrayList();
paramMap.put("startNum", String.valueOf(i+1));
paramMap.put("endNum", String.valueOf(i+5000));
paramMap.put("instFlag", instFlag);
paramMap.put("vDate", vdate);
rs = executeSqlDao.queryForList("SELECT-SMS-SingleData-LIST",paramMap);
if (rs!=null){
for(int j=0; j<rs.size(); j++){
list.add(rs.get(j));
}
}
}
if(list != null && list.size() >= 1) {
Set set = commonService.getLogoValue(null);
for(int m = 0;m < list.size();m++) {
msdd = (OmsSingleDataDTO)list.get(m);
if(!OrderBaseService.getLogIsValid(msdd.getCardNo(),"14",set)) {
// 更新处理状态
this.updateMosSingleData2(msdd.getSeqId());
continue;
}
String custNo = msdd.getCustNo();
custNo = custNo.length() >= 12 ? custNo.substring(custNo.length() - 12):custNo;
msdd.setCustNo(custNo);
SmsList.add(msdd);
}
}
return SmsList;
}
以上是使用的一次全部查询出数据,然后一次写入到文件中,但是这种方法会用几个小时才能完全写入。下面是自己优化后的方案:
public void generateSMSFile(String localFilePath,String date) throws Exception{
try {
File file1 = FileUtils.createFile(localFilePath);
BufferedWriter bw = FileUtils.getWrite(file1);
StringBuffer buffer = new StringBuffer("S|1|S0180||||");
List smslistCount = getSingleDataSMS("03", date);
buffer.append(smslistCount.size() + "|");
buffer.append("\r\n");
List subList = new ArrayList();
List listid = new ArrayList();
int count = 1;
int total = 0;
total = generateSMSFilestpeSize(date);
//防止大于1万条时出错,循环处理
for(int k=0; k<total; k+=5000){
List smsList = getSingleDataSMSstep("03", date, k, k+5000);
if(smsList != null && smsList.size() != 0) {
for(int i = 0;i < smsList.size();i++) {
OmsSingleDataDTO msdd = (OmsSingleDataDTO)smsList.get(i);
String transDate = msdd.getTransDate();
String leastDate = msdd.getLeastDate();
count = count +1;
buffer.append(String.valueOf(count));
buffer.append("|");
buffer.append(msdd.getMobile());
buffer.append("|");
buffer.append(msdd.getCustNo());
buffer.append("|");
buffer.append(transDate.substring(5,7));
buffer.append("|");
buffer.append(transDate.substring(8,10));
buffer.append("|");
buffer.append(msdd.getTransAmount());
buffer.append("|");
buffer.append(msdd.getFirstAmount());
buffer.append("|");
buffer.append(msdd.getEachAmount());
buffer.append("|");
buffer.append(leastDate.substring(4,6));
buffer.append("|");
buffer.append(leastDate.substring(6,8));
buffer.append("|");
buffer.append(msdd.getConsumeCode());
buffer.append("|");
buffer.append("\r\n");
subList.add(msdd.getSeqId());
if((i+1)%5000==0){
listid.add(subList);
subList=new ArrayList();
}
}
listid.add(subList);
}
bw.write(buffer.toString());
buffer = new StringBuffer();
if(listid != null && listid.size() >= 1) {
for(int i=0;i<listid.size();i++) {
OMSLogger.info("保费类 - 第"+ (count) +"次运行开始");
long msBefore = System.currentTimeMillis();
updateMosSingleData((List)listid.get(i));
long msAfter = System.currentTimeMillis();
OMSLogger.info("保费类 - 第"+ (count) +"次运行结束,共耗时" + (msAfter - msBefore) + "毫秒");
}
}
}
bw.close();
} catch (Exception e) {
OMSLogger.error("生成单笔分期批量短信文件异常");
throw new Exception("生成单笔分期批量短信文件异常",e);
}
}
每次获取5000条数据返回list,写入文件之后再次执行该方法在获取5000条数据
private List getSingleDataSMSstep(String instFlag,String vdate,int startNum,int endNum) throws PafaDAOException {
List SmsList = new ArrayList();
List list = new ArrayList();
OmsSingleDataDTO msdd = null;
HashMap paramMap =new HashMap();
List rs = new ArrayList();
paramMap.put("startNum", startNum);
paramMap.put("endNum", endNum);
paramMap.put("instFlag", instFlag);
paramMap.put("vDate", vdate);
rs = executeSqlDao.queryForList("SELECT-SMS-SingleData-LIST",paramMap);
if (rs!=null){
for(int j=0; j<rs.size(); j++){
list.add(rs.get(j));
}
}
if(list != null && list.size() >= 1) {
Set set = commonService.getLogoValue(null);
for(int m = 0;m < list.size();m++) {
msdd = (OmsSingleDataDTO)list.get(m);
if(!OrderBaseService.getLogIsValid(msdd.getCardNo(),"14",set)) {
// 更新处理状态
this.updateMosSingleData2(msdd.getSeqId());
continue;
}
String custNo = msdd.getCustNo();
custNo = custNo.length() >= 12 ? custNo.substring(custNo.length() - 12):custNo;
msdd.setCustNo(custNo);
SmsList.add(msdd);
}
}
return SmsList;
}
补充一个自己写的小例子:
package myTempTest; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException; public class ioTestBuffer {
public static void main(String[] args) throws IOException {
File file1 = new File("d:\\io\\out.txt");//最终写入文件地址
BufferedWriter bw = new BufferedWriter(new FileWriter(file1));
StringBuffer buffer = new StringBuffer("");
for (int j = ; j < ; j++) {
//之所以I循环1W次就写出一次,是因为buffer超过1W次append之后极容易在次append的时候报错。
for (int i = ; i < ; i++) {
buffer.append(i+""+i+""+i+""+i+""+i+""+i+""+i+""+i+""+i+""+i+"");
buffer.append("\r\n");//换行
}
bw.write(buffer.toString());//1W次I循环结束 写入到文件中
buffer = new StringBuffer("");//格式化buffer。
buffer.append(j+"-------------------------------------");//第 j 此循环加上个记号
buffer.append("\r\n");//一次J循环结束 换行
}
bw.close();
}
}
关于BufferedWriter.write超过30W条数据写入过慢问题。的更多相关文章
- net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎
序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...
- 我分析30w条数据后发现,西安新房公摊最低的竟是这里?
前两天一个邻居发出了灵魂质问:"为什么我买的180平和你的169平看上去一样大?" "因为咱俩的套内面积都是138平......" 我们去看房子,比较不同楼盘的 ...
- 通过Excel导入Mysql 超过65535条数据的办法
1.截取 65534条数据,进行分sheet,然后1个sheet导入一张表,最后进行整合! 2.采用TXT导入方式,TXT的导入暂时没发现限制的数据条数,下午用TXT导入74万条数据成功 3.如果遇到 ...
- 将Excel上千条数据写入到数据库中
简要说明:因工作需要,需要一张Excel表格中的所有数据导入到数据库中.如下表,当然这只是一部分,一共一千多条. 前期处理: 首先要保证上图中的Excel表格中的数据不能为空,如果有为空的数据,可以稍 ...
- 《项目经验》--通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中
先看一下我要实现的功能界面: 这个界面的功能在图中已有展现,课程分配(教师教授哪门课程)在之前的页面中已做好.这个页面主要实现的是授课,即给老师教授的课程分配学生.此页面实现功能的步骤已在页面 ...
- 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中
摘自:http://blog.csdn.net/mazhaojuan/article/details/8592015 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来 ...
- oracle select in超过1000条报错解决方法
本博客介绍oracle select in超过1000条数据的解决方法,java框架是采用mybatis的,这可以说是一种比较常见的错误:select * from A where id in(... ...
- SqlBulkCopy批量写入25万条数据只需3s
Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上).SqlBulkCopy ...
- 运用BufferedWriter把数据写入文件
public class WriteReadFiles { private static Logger log = LoggerFactory.getLogger(WriteReadFiles.cla ...
随机推荐
- linux:计算机概论
1>.计算机的五大单元:输入单元.输出单元.CPU内部的控制单元.算术逻辑判断单元和主记忆体单元(记忆体包含主记忆体和辅组记忆体): 2>.CPU分为两类:精简微指令集(RISC)和复杂微 ...
- Redis:安装
此篇文章并不介绍linux下安装方法.围绕windows安装而介绍 两种安装方式: 1)下载压缩包,解压后(运行起来有个窗口,关闭掉就不在运行),没有windows服务被注册:可以只用命令在cmd将其 ...
- networkcommon v3开源消息框架资料
http://www.cnblogs.com/csdev/category/870400.html
- MVC 学习系列
总是很难说清MVC的概念,即使读了源代码后(读的时候有些东西,理解起来还是有点吃力),也依然能难对整体的每一个具体的原理说的一清二楚.为了达到自己学习的目的,我把自己的学习路线写成文章,一边自己能对M ...
- c++的用处
C++准确说是一门中级语言,介于汇编和高级语言之间吧,要求程序员了解计算机的内部数据存储.个人认为,作为学生还是花功夫学C++,因为<设计模式><数据结构>这些课程基本上还是C ...
- HDU 3308 LCIS(线段树)
Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (in ...
- 。。。无语的Eclipse+Tomact。。。
晕哦,今天又被Eclipse给骗了,今天部署了一个SSH的环境,搞了半天,JAR包是通过BuildPath导入进去的,怎么搞都报错,说是找不到Spring-Web的一个Jar包,差点没有把我给弄死.. ...
- 关于LED 流水灯的软件调试方法(非开发板调试)
因为: 硬件 norflash 有寿命,所以尽量少用,而且自己也不会把 程序在 KEIL中从SDRAM 中调试,不会设置.所以采取软件虚拟的方法调试. 主要修改一下几部分: 1. ledcircle ...
- paper 51:图像复原
图像退化: 图像在形成.记录.处理和传输过程中,由于成像系统.记录设备.传输介质和处理方法的不完善,导致图像质量的下降,这种现象叫做图像退化. 图像复原: 就是对退化的图像进行处理,尽可能恢复出原始 ...
- Android应用开发中的风格和主题(style,themes)
http://www.cnblogs.com/playing/archive/2011/04/01/2002469.html 越来越多互联网企业都在Android平台上部署其客户端,为了提升用户体验, ...