之前印象中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(" ", "") ); 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(" "); } 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(" ", "") + 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 + " "; } 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(); } }