关于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>.系统里面必须最少有两个账号,一个root,一个普通账户; 2>.平时登录系统均使用普通账户登录,除非需要配置或者执行特殊命令才切换至root; 3>.linux系统下严格区分大 ...
- PAT 解题报告 1050. String Subtraction (20)
1050. String Subtraction (20) Given two strings S1 and S2, S = S1 - S2 is defined to be the remainin ...
- 使用Java创建RESTful Web Service
REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移).2000年Roy Fielding博士在他的博士论文“Architectural Sty ...
- Swift实战-豆瓣电台(六)视图跳转,传参及回跳
youku观看地址:http://v.youku.com/v_show/id_XNzMxMzQ3MDcy.html 要点 在ChannelController里面声明一个代理 这个代理遵循我们自定义的 ...
- ngrok外网登录本地Web服务器
首先在网上下载ngrok软件,然后cmd到其目录下,运行ngrok http 80即可打开服务器,然后自动生成外网连接,然后C:\inetpub\wwwroot下放置html网页,在公网即可打开
- raid0
RAID0把数据分割之后放在各个硬盘上,同时读写以提升数据带宽其实在固态硬盘还没有大量出现在零售市场中之前,玩家想要大幅度提升硬盘系统的性能,最常用的方法就是组建RAID0系统.原理很简单,就以SAT ...
- JavaScript读写脚txt文件
1.cmd切换到“C:\Windows\System32>”下,执行“regsvr32 Scrrun.dll” 2.JavaScript读写txt文本代码如下,注意要发布到服务器上 <!D ...
- struts_20_对Action中所有方法、某一个方法进行输入校验(基于XML配置方式实现输入校验)
第01步:导包 第02步:配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app ...
- GitHub和SourceTree入门教程——(转载),希望能帮到有需要的人
-->本教程适用于主流的开源网站github和bitbucket,个人认为sourceTree还是比较好用的git客户端,支持windows和mac os. -->soureceTree的 ...
- 动态时间规整(DTW) 转载
Dynamic Time Warping(DTW)诞生有一定的历史了(日本学者Itakura提出),它出现的目的也比较单纯,是一种衡量两个长度不同的时间序列的相似度的方法.应用也比较广,主要是在模板匹 ...