下面这段代码是读一个2进制文件,通过一定规则转码然后导出数据到txt,因为该公司有安全要求,map类我就不给了,还有用map来影射是不是效率很慢呢?我用什么去代替它比较好?最重要的是麻烦各位大虾帮我看看下面的代码哪有影响效率的地方。请赐教package test;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import cn.com.swt.MapISO;
import cn.com.swt.MapSUD;
public class TestEOF {
  // Throw exceptions to console:
MapISO map = new MapISO();
MapSUD sudmap = new MapSUD();
String nameAll;
public static void main(String args[])
{
TestEOF test = new TestEOF();
Date a = new Date();
System.out.println(a);//开始时间  
try {

test.outTxt("d:\\0000000015","d:\\test.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Date b = new Date();
System.out.println(b);//结束时间
}
  public void  outTxt(String imPath,String outPath) throws IOException {
  ChangeCharset test = new ChangeCharset();
  InputStream is = new FileInputStream(imPath); 
      byte[] b = new byte[is.available()]; 
      is.read(b); 
      is.close(); 
      int sudd = Integer.parseInt(byte2hex(b,53,54), 16);
  String sud = sudmap.getmap().get(String.valueOf(sudd)).toString();
      String name1 =byte2hex(b,1,2);
      String name2 =byte2hex(b,2,3);
      String name3 =byte2hex(b,3,4);
      nameAll =map.getmap().get(name1).toString()+map.getmap().get(name2).toString()+map.getmap().get(name3).toString()+" SUBSCRIBER DATA"+"\r\n";
File f=new File(outPath); 
String a = getContent(b,nameAll);
writeStr(f,a);
  }
  
  public static String byte2hex(byte[] b,int start,int end) { 
      String hs = ""; 
      String stmp = ""; 
      for (int a = start; a < end; a++) { 
          stmp = (java.lang.Integer.toHexString(b[a] & 0XFF)); 
          if (stmp.length() == 1) { 
              hs = hs + "0" + stmp; 
          } else { 
              hs = hs + stmp; 
          } 
      } 
      return hs.toUpperCase(); 
 }
  public static String changeCharset(String str, String newCharset)
  throws UnsupportedEncodingException {
 if (str != null) {
  //用默认字符编码解码字符串。
  byte[] bs = str.getBytes();
  //用新的字符编码生成字符串
  return new String(bs, newCharset);
 }
 return null;
}
  /*输出文本文件方法*/
  private void writeStr(File f,String str){
// File f=new File(outPath);  
   BufferedWriter bw=null;
   try {
    bw=new BufferedWriter(new FileWriter(f));
    bw.write(str);
    bw.flush();
   } catch (Exception e) {
    System.out.println(e.getMessage());
   }finally{
    try {
     if(bw!=null){
      bw.close();
     }
    } catch (Exception e) {
    }
   }
}
  //获得每条记录
  //number 是记录编号    
  private String getContent (byte[] b,String name)
  {
  String[] IMSIS;
  String[] MSISDNS ;
  String IMSI = null;
  String MSISDN =null;
  String sud = null;
  String sudValue = null;
  String userValues ="";
  String NAM = null;
  
  int dateStart = 32;//32个字符以后存的内容是用户数据
  int num ;   //数据编号
  for( dateStart=32,num =1 ; dateStart<b.length;dateStart++) 
//   for( dateStart=32,num =1 ; dateStart<500;dateStart++)  
  {
  System.out.println(dateStart);
  String NUM = Integer.toOctalString(num);
  for(int t = NUM.length();t<6;t++)
  {
  NUM = "0"+NUM;
  }
  String numBiaoshi = "32"+NUM;
  if (dateStart+4>=b.length)
  {
  break;
  }
  if(byte2hex(b, dateStart,dateStart+4).equals(numBiaoshi))//找到数据的开头
  {
  IMSIS = byte2hex( b,dateStart+4,dateStart+12).split("F");//去掉用F填充的无用数据
  for(int w = IMSIS[0].length();w<17;w++)
  {
  IMSIS[0]+=" ";
  }
  IMSI = IMSIS[0];//得到IMSI数据
  MSISDNS = byte2hex(b,dateStart +12,dateStart+20).split("F");//去掉用F填充的无用数据
  for(int v = MSISDNS[0].length();v<17;v++)
  {
  MSISDNS[0]+=" ";
  }
  MSISDN = MSISDNS[0];//得到MSISDN数据
  int  l = 0; 
  String sudValues[]=new String[100] ;
  for(int s = dateStart+21;s<b.length;s+=3)//把每一个SUD数据存在sudValues[]队列中
  {   
  if(!byte2hex(b,s,s+1).equals("FF"))
  {
 
  String value ;
  sud = sudmap.getmap().get(String.valueOf(Integer.parseInt(byte2hex(b,s,s+1), 16))).toString();
 
 
  sudValue = String.valueOf(Integer.parseInt(byte2hex(b,s+1,s+3),16));
  if(sud=="NAM")
  {
  NAM = sudValue;//NAM数据不存在SUD数据中,单独显示
  continue;
  }
 
  String content = sud+"-"+sudValue;
  for(int m=content.length();m<13;m++)//每个数据占13个字节
  {
  content =" "+content;
  }
  sudValues[l++]=content; 
  }
  else{
  break;
  }
  }
  for(int j =0;j<sudValues.length;j++)//SUD每4条记录换一行
  {
  if((j+1)%4==0)
  {
  sudValues[j]=  sudValues[j]+"\r\n";
  }
  }
  String allSudvalues = "";
  int k ;
  for(k =0 ;k<sudValues.length&&sudValues[k]!=null;k++)//SUD数据存在String allSudvalues中
{
  allSudvalues= allSudvalues+sudValues[k];
}
  //把每条完整记录存在userValues中
  userValues = userValues + "<hgsdp:imsi="+IMSI+",all;\r\n" 
  +name+"\r\n\r\n"+"SUBSCRIBER IDENTITY"+"\r\n"+"MSISDN           IMSI             STATE          AUTHD"+"\r\n"
  +MSISDN+IMSI+"CONNECTED      AVAILABLE"+"\r\n"+"\r\n"+"NAM"
  +"\r\n"+NAM+"\r\n\r\n"+"PERMANENT SUBSCRIBER DATA"+"\r\n"+"SUD"+"\r\n"+
  allSudvalues+"\r\n" +"END"+"\r\n\r\n\r\n";
  num = num+1;
  dateStart = dateStart+k*3;
  System.out.println(dateStart);
  }
  
  }
  return userValues;
  }
}

解决方案 »

  1.   

    我大概扫了一遍,
    比如:
    InputStream is = new FileInputStream(imPath); 
    byte[] b = new byte[is.available()]; 
    is.read(b);
    这个地方就可以用bufferInputStream修饰器再去修饰,很少有人会这样直接使用java IO
    这仅仅是一个很小的地方,这是java 1.0的做法,
    java 1.1有新的java.nio..,通道,缓冲器,映射文件的概念都是为了最大程度的提高IO的效率,你并没有使用到。
    1:读byte可以缓冲器去读,
    2:你是一个个读一个个写,一次读出放入内存中,比如bytearrayinputstream,再一次性写入,也比你这来的快。
    3:如果2你不愿意这样做的话。你可以使用映射文件。
    你的做法确实不是最快的一种。
      

  2.   

    你的IO操作太多了,不要老是NEW,OPEN.CLOSE,要学会充分利用资源,建立缓存或者池,提高这些操作的效率
      

  3.   

    楼上各位的意见都值得借鉴。
    我想要补充一条。你仔细浏览一下你的代码,for循环的嵌套达到三层之多!!
    在正常情况下,只要达到三层循环嵌套,代码就必须要进行优化。或者是进行程序设计的优化。
    很多情况下这也是造成效率低下的一个非常主要的原因。
    仔细研究一下,有没有哪些东西你用了两次循环甚至更多,而其实是可以放到一次里面就解决的?
    你的循环实在是很多啊~~再说一点精细的地方,尽量在循环中少做判断,一般多数 情况尽量if在外,for在内。就像车在路上跑,只进行一次检查后就连着跑很多圈的速度一定会比每圈都停下来做检查快很多的。
    呵呵,努力吧,加油,最痛苦的时候,也是最增长经验的时候。挺住~~
      

  4.   

    我的毕设就是一个处理大量数据的程序
    处理500个TXT文件,而且比对(处理)的次数也很多 不过运行一次才10分钟
    如果处理十几M的txt的话 至少也得个几分钟吧
    如果处理的txt不是很大 那就是你的程序设计的问题了
    我也比较同意5楼的 你的for嵌套的太多了 写把这个改进一下 看看效率
    PS:在每个函数的入口和出口都打印时间(不只是程序的入口和出口)
         这样看看哪个函数最耗时