nio代码片段


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.huateng.common.service.CommonBaseService;
import com.huateng.common.util.Assert;
import com.huateng.common.util.Constant;
import com.huateng.common.util.DateUtil;
import com.huateng.common.util.StringUtils;
import com.ums.bke.outerdata.settle.createfile.dao.SettleCreateFileDao;


/**
 * desc:创建文件
 */
@Service
public class SettleCreateFileService extends CommonBaseService{

	@Autowired
	private SettleCreateFileDao settleCreateFileDao;
	
	@Override
	public SettleCreateFileDao getBaseDao() {
		return settleCreateFileDao;
	}
	
	
	/**
	 * 查询启用的清分文件生成方案
	 * @return
	 */
	private Map<String, String> getDisplayInfo(){
		return settleCreateFileDao.getDisplayInfo();
	}
	
	/**
	 * 查询清分文件生成所用到的字段
	 * @return
	 */
	private List<String> getDisplayField(Object obj){
		return settleCreateFileDao.getDisplayField(obj);
	}
	

	/**
	 * 获取清分数据。因数据量可能很大,为方式内存溢出,所以采用分批获取的方式(也就是分页方式)<br/>
	 * LinkedHashMap是一个有序的map
	 * @return
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	private List<LinkedHashMap<String, String>> getSettleInfo(List<String> fieldList, int currentPage) throws Exception{
		//组织分页信息
		Map map = new HashMap();
		map.put("fieldList", fieldList);//要查询的字段
		
		int pageSize = 1000; //批量查询,每批可查询的数据条数
		RowBounds bounds = new RowBounds(currentPage * pageSize, pageSize);
		return this.settleCreateFileDao.getSettleInfo(map, bounds);
	}
	
	
	/**
	 * 创建文件
	 * @throws Exception 
	 */
	public void doCreateFile() throws Exception{

		//1 -查询启用的清分文件生成方案
		Map<String, String> map = getDisplayInfo();
		Assert.isTrue(null!=map && map.size()!=0, "未找到对应的清分文件生成方案!");
		log.info("清分文件圣生成方案:" + map);
		String fieldSeparator = MapUtils.getString(map, "RESV2", "|"); //字段分隔符,默认分隔符是|
		
		//2 - 根据方案,查询清分文件生成所用到的字段
		List<String> fieldList = getDisplayField(map);
		Assert.isTrue(null!=fieldList && fieldList.size()!=0, "清分文件生成方案中没有配置查询字段!");
		log.info("清分文件要查询的字段:"+ fieldList.size() + fieldList);
		
		//分批次从清分库中获取数据,并写入文件中
		String fileName = "selltle_" + DateUtil.getStrDate("yyyyMMddHHmmssSSS") + ".txt.tmp";
		FileOutputStream stream = new FileOutputStream(Constant.SETTLE_SAVE_DIR + fileName);
        FileChannel channel = stream.getChannel();//根据FileOutputStream获得通道FileChannel
        int currentPage = 0;//从0开始计算批次
        try {
			while (currentPage >= 0) {
				log.info("从清分中提取数据,(批次从0开始计算)当前批次currentPage是:" + currentPage);
				List<LinkedHashMap<String, String>> settleList = this.getSettleInfo(fieldList, currentPage);// 此处根据currentPage调用service获取数据
				if (null != settleList && settleList.size() > 0) {
					log.info(String.format("当前输出批次(批次从0开始计算)是:%s, 该批次共有数据%s条!", currentPage, settleList.size()));
					for (int i = 0; i < settleList.size(); i++) {
						StringBuffer sbf = new StringBuffer();
						LinkedHashMap<String, String> linkMap = settleList.get(i);
						for (int j = 0; j < fieldList.size(); j++) {
							String key = fieldList.get(j);
							String value = linkMap.get(key);
							sbf.append(fieldSeparator);//分隔符
							sbf.append(StringUtils.nvl(value, ""));
						}
						sbf.deleteCharAt(0).append("\r\n");//去掉首字母的分隔符,并在最后增加换行符
				        channel.write(ByteBuffer.wrap(sbf.toString().getBytes()));//字节方式写入  
					}
					currentPage++;//取下一批数据
				} else {
					log.info("准备跳出while循环,(批次从0开始计算)总批是:" + currentPage);
					currentPage = -1;//当前批次取到的数据为空,则说明所有数据已取完,并跳出while循环
				}
			}
			log.info("已跳出while循环!");
		}catch(Exception e){
			channel.write(ByteBuffer.wrap("\r\n".getBytes()));//输出换行
			channel.write(ByteBuffer.wrap(StringUtils.getStackTrace(e).getBytes()));//将异常信息输出到文件
			//生成文件出错
			this.close(channel, stream);
			//重命名文件,将文件恢复为error的后缀
			this.renameTo(Constant.SETTLE_SAVE_DIR + fileName, Constant.SETTLE_SAVE_DIR + fileName.replaceAll("\\.tmp", ".err"));
			throw new Exception("生成清分文件异常,(批次从0开始计算)当前批次:" + currentPage, e);
		} finally {
			this.close(channel, stream);
		}
		//重命名文件,将文件恢复为正常的后缀
		this.renameTo(Constant.SETTLE_SAVE_DIR + fileName, Constant.SETTLE_SAVE_DIR + fileName.replaceAll("\\.tmp", ""));
		log.info("生成清分文件完毕");
	}
	
	/**
	 * 关闭流
	 * @param channel
	 * @param stream
	 * @throws IOException
	 */
	private void close(FileChannel channel, FileOutputStream stream ) throws IOException{
		channel.close();
		stream.flush();
		stream.close();
		log.info("关闭通道,刷新流,生成文件完毕!");
	}
	
	/**
	 * 重命名文件
	 * @param file
	 * @param fileTo
	 * @return
	 */
	private boolean renameTo(String file, String fileTo){
		//重命名文件,将文件恢复为正常的后缀
		File temFile = new File(file);
		File newFile = new File(fileTo);
		boolean brendame = temFile.renameTo(newFile);
		log.info(String.format("%s->%s文件重命名结果为:%s", file, fileTo, brendame));
		return brendame;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值