关于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 ...
随机推荐
- NSMutableDictionary中元素替换
NSMutableDictionary *dic = [NSMutableDictionary new]; [dic addEntriesFromDictionary:@{@"key&quo ...
- dev c++ 的一些快捷键
Ctrl+N新建源代码Ctrl+O打开工程或源文件Ctrl+S保存Ctrl+Alt+S另存为Ctrl+W关闭Ctrl+P打印Ctrl+Z回复Ctrl+Y重做Ctrl+Q切换头/源文件Ctrl+.注释C ...
- demo07
city_data.xml <?xml version="1.0" encoding="utf-8"?> <resources> < ...
- linux进程自动关闭与dmesg的使用
一些应用程序,后台服务被关掉.例如内存不足等,可能是操作系统关掉的.这些日志记录在dmesg中. 存储目录:/var/log/dmesg dmesg -T 可以将时间戳转化为可以识别的时间. | he ...
- linux的vim按了ctrl+s之后假死的解决办法
习惯了很多软件的保存的快捷键,经常在vim中按下ctrl+s,然后就发现vim不响应了,之间一直采用kill的方式解决,近来搜了一下,是这样子的: 这时的vim并没有死掉,只是vim不再向终端输出东西 ...
- [OrangePi] Backup internal EMMC to SD Card
Boot your Orange PI board from EMMC without SD Card inserted login insert your SD Card Run: sudo ins ...
- 关于陈冰、陈良乔以及《我的第一本C++书》【转】
出处:如何在淘宝上卖出 600 本自己写的 C++ 入门书? 陈冰:<我的第一本C++书> 策划编辑,现为图灵公司副总编,<C程序设计伴侣>策划编辑 陈良乔:<我的第一本 ...
- decimal.tostring()格式
nt/Decimal.ToString 方法 (String, IFormatProvider) decimal value = 16325.62m; string specifier; Cult ...
- android 弹幕效果demo
记得之前有位朋友在我的公众号里问过我,像直播的那种弹幕功能该如何实现?如今直播行业确实是非常火爆啊,大大小小的公司都要涉足一下直播的领域,用斗鱼的话来讲,现在就是千播之战.而弹幕则无疑是直播功能当中最 ...
- linux设备驱动归纳总结(三):6.poll和sellct【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-61749.html linux设备驱动归纳总结(三):6.poll和sellct xxxxxxxxxx ...