之前印象中string与stringbuilder操作时,如果多次改变string就使用stringbuilder,效率会提高;
今天实际遇到了问题,亲身经历过之后,这性能不是一般的影响啊;不是同一个数量级的;
场景描述:
一个包含50719条记录的excel文件,读取其中的内容,通过逗号分隔的方式拼接成字符串;
如果使用string要耗时三四十分钟;有可能更长,并且耗费更多的内存;
如果使用stringbuilder只需要几秒钟;有可能更短;
测试代码如下:
使用stringbuilder
/**
* v1.1 excel转txt 输入excel流,返回txt流
* @param ins excel流
* @param filename2 txt临时文件路径
* @param split_char 分割符
* @param Column 总列数
* */
private boolean ExcelToTxt(InputStream ins, String filename2, String split_char, String Column){
boolean flag = false;
Workbook rwb = null;
FileOutputStream fops = null;
Sheet rs = null;
Cell cell = null;
String split_char_real = ",";//实际分隔符
if(split_char!=null && split_char.trim().length()>0){
split_char_real = split_char;
}
//获得文件名
//String filename1 = filename.substring(0,filename.lastIndexOf("."));
//路径+文件名+.txt后缀
//String filename2 = path+"/"+filename1+".txt";
//创建txt临时文件
File newFile = new File(filename2);
try {
//从输入流创建Workbook
rwb = Workbook.getWorkbook(ins);
//获取第一张Sheet表
rs = rwb.getSheet(0);
//获取Sheet表中所包含的总列数
int rsColumns = rs.getColumns();
if(Column!=null && Column.trim().length()>0){
rsColumns = Integer.valueOf(Column);//使用配置的列数
}
//获取Sheet表中所包含的总行数
int rsRows = rs.getRows();
//拼接内容
StringBuilder s = new StringBuilder();
for(int i=0;i<rsRows;i++){
// cell = rs.getCell(0,i);//每行的第一个
// if(cell.getContents().trim().length()==0){//如果第一列为空就结束读取excel
// break;
// }
//判断是否为空行
try {
StringBuilder rowData = new StringBuilder();
for(int j=0;j<rsColumns;j++){
cell = rs.getCell(j,i);
rowData.append(cell.getContents());
}
if (new String(rowData).trim().length() == 0) { //如果为空行,就结束读取excel
break;
}
} catch (Exception e) {
System.out.println("*****DataImport*********** 判断空行出错");
e.printStackTrace();
break;
}
for(int j=0;j<rsColumns;j++){
cell = rs.getCell(j,i);
String content = cell.getContents();
s.append(content.replaceAll("\n", "") );
s.append(split_char_real);//支持换行
}
if(s.length()>0) s.delete(s.length()-split_char_real.length(),s.length());//s = s.substring(0,s.length()-split_char_real.length());
//
/*if(s.length()>0 ){
int count = StringUtils.countMatches(s, split_char_real);
//&& s.split(split_char_real).length>0 && s.split(split_char_real).length < rsColumns
s = s + split_char_real+ " ";
}*/
if(s.lastIndexOf(split_char_real) == (s.length() - split_char_real.length())){
s.append(" ");
}
if(i<rsRows-1) s.append("\r\n");
}
System.out.println("--------DataImport---------excel转换生成的txt文件内容:"+newFile.getAbsolutePath());
if(!newFile.exists()){//如果文件不存在,就创建一个新的
newFile.createNewFile();
}
fops = new FileOutputStream(newFile);//使用输出流
fops.write(s.toString().getBytes());//写入文本文件
flag = true;//转换成功
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
//操作完成时,关闭对象,释放占用的内存空间
rwb.close();
try {
fops.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return flag;
}
public static void main(String[] args) {
DataImport di = new DataImport();
try
{
di.ExcelToTxt(new FileInputStream("f:\\团圆行动营销成功客户上传_20140610.xls"), "f:\\2014.txt", ",", "10");
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
使用string
/**
* v1.1 excel转txt 输入excel流,返回txt流
* @param ins excel流
* @param filename2 txt临时文件路径
* @param split_char 分割符
* @param Column 总列数
* */
private boolean ExcelToTxt(InputStream ins, String filename2, String split_char, String Column){
boolean flag = false;
Workbook rwb = null;
FileOutputStream fops = null;
Sheet rs = null;
Cell cell = null;
String split_char_real = ",";//实际分隔符
if(split_char!=null && split_char.trim().length()>0){
split_char_real = split_char;
}
//获得文件名
//String filename1 = filename.substring(0,filename.lastIndexOf("."));
//路径+文件名+.txt后缀
//String filename2 = path+"/"+filename1+".txt";
//创建txt临时文件
File newFile = new File(filename2);
try {
//从输入流创建Workbook
rwb = Workbook.getWorkbook(ins);
//获取第一张Sheet表
rs = rwb.getSheet(0);
//获取Sheet表中所包含的总列数
int rsColumns = rs.getColumns();
if(Column!=null && Column.trim().length()>0){
rsColumns = Integer.valueOf(Column);//使用配置的列数
}
//获取Sheet表中所包含的总行数
int rsRows = rs.getRows();
//拼接内容
String s = "";
for(int i=0;i<rsRows;i++){
// cell = rs.getCell(0,i);//每行的第一个
// if(cell.getContents().trim().length()==0){//如果第一列为空就结束读取excel
// break;
// }
//判断是否为空行
try {
StringBuilder rowData = new StringBuilder();
for(int j=0;j<rsColumns;j++){
cell = rs.getCell(j,i);
rowData.append(cell.getContents());
}
if (new String(rowData).trim().length() == 0) { //如果为空行,就结束读取excel
break;
}
} catch (Exception e) {
System.out.println("*****DataImport*********** 判断空行出错");
e.printStackTrace();
break;
}
for(int j=0;j<rsColumns;j++){
cell = rs.getCell(j,i);
String content = cell.getContents();
s = s + content.replaceAll("\n", "") + split_char_real;//支持换行
}
if(s.length()>0) s = s.substring(0,s.length()-split_char_real.length());
//
if(s.length()>0 && s.split(split_char_real).length>0 && s.split(split_char_real).length < rsColumns){
s = s + split_char_real+ " ";
}
if(i<rsRows-1) s = s + "\r\n";
}
System.out.println("--------DataImport---------excel转换生成的txt文件内容:"+s);
if(!newFile.exists()){//如果文件不存在,就创建一个新的
newFile.createNewFile();
}
fops = new FileOutputStream(newFile);//使用输出流
fops.write(s.getBytes());//写入文本文件
flag = true;//转换成功
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
//操作完成时,关闭对象,释放占用的内存空间
rwb.close();
try {
fops.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return flag;
}
public static void main(String[] args) {
DataImport di = new DataImport();
try
{
di.ExcelToTxt(new FileInputStream("f:\\团圆行动营销成功客户上传_20140610.xls"), "f:\\2014.txt", ",", "10");
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}