目前遇到这样一个问题:
需要读取这样一个txt文件,内容示例:
#1234|abcd|7|1104044644|20.1.1.61
#|abcd|8|1204044644|20.1.1.61
...
比如这样是一对,假设有10000对,也就是20000行
判断abcd这个位置的字符串和最后的20.1.1.61相同的为一组,处理文件中所有的行数因为文件的内容会增加,所以需要定位上次读取后的指针位置
故我使用了RandomAccessFile(File file)功能我能实现,但是效率不行,25000行在4000毫秒左右,要求超大幅度降低时间
所以希望高手指导下是否要换用其他的流,在collection的选择上哪种最效率,处理过程中哪里可以优化我的测试codepublic class Test {
private static String srcfile = "d:\\T.txt";
public static void main(String[] args) {
Long long1 = System.currentTimeMillis();
Long position = 0l;
Map<String, String> up = new HashMap<String, String>();
List<BIDR> gatherList = new ArrayList<BIDR>();
RandomAccessFile raf = null;
BufferedReader br = null;
try {
raf = new RandomAccessFile(srcfile, "r");
raf.seek(position);
String line = raf.readLine();
while (null != line) {
StringTokenizer st = new StringTokenizer(line, "|");
List list = new ArrayList();
String ip = null;
while (st.hasMoreTokens()) {
list.add(st.nextToken());
}
if ("7".equals(list.get(2))) { String name = (String) list.get(0);
String jiqi = (String) list.get(1);
ip = (String) list.get(4);
String time = (String) list.get(3);
up.put(jiqi + ip, name.substring(1) + "#" + time);
} else {
String jiqi = (String) list.get(1);
ip = (String) list.get(4);
String str = up.get(jiqi + ip);
if (null != str) {
BIDR b = new BIDR();
String[] arry = str.split("#");
b.setAAA_login_name(arry[0]);
long l1 = Long.parseLong(arry[1]);
long l2 = Long.parseLong((String) list.get(3));
b.setLogin_date(new Timestamp(l1));
b.setLogin_ip(ip);
b.setLogout_date(new Timestamp(l2));
b.setTime_deration((int) (l2 - l1) / 6000);
gatherList.add(b);
}
}
line = raf.readLine();
}
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Long long2 = System.currentTimeMillis();
System.out.println(long2 - long1);
}
}

解决方案 »

  1.   

    同志, 一般情况下, 谁都会第一时间用你这类的办法, 人之天性, 追求方便.
    但是, 如果你追求的是速度, 那么我和你分享一下我的一些办法:
    1, 选择最快读取文件的方法, 一般来说, 最快读取文件的api与操作系统拷贝文件等速. 我猜想你用读行的办法与读二进制块的办法速度差别不大.
    2, 不要事事依靠api, 这样的程序是没有灵魂的, 也就是你没有彻底控制自己代码. 上边读文件就没有办法了, 只能借助操作系统, 但读了文件以后, 自己做自己的缓冲区.
    3, 承接第二点, 不用arraylist这类的高级对象, 尽可能用第一代语言就已经具有的原始的东西:数组,这是本真.你去看看大师作品,有几个是用这些华丽对象的.
    4,你的问题虽然我看不懂,但大概知道要对字串进行解拆,这时候你最好学习一下有穷自动机的理论.如果你不了解,没关系,因为最时尚的所谓正则表达式就是与之等价.但不要化太多时间去死磕某种语言里某类api的正则表达式,这是眼见功夫而已.自己构造自己的极速自动机才是王道.
    5,任何事物都有个极限,比方我做全文检索的分词,顶了天也就做到1M字节/s的分词速度,只要你心理有数,算法的时间复杂度已经达到极限了,再死磕也就能在系数上抠,这时就不要勉强了.CSDN所谓分数将人变得市侩.有分就象苍蝇看到屎一样围着转,没分连个人影都没有.
      

  2.   

    我是个初学者,实在感谢楼上的建议
    我已经放弃RandomAccessFile了
    使用BufferedReader等其他流,速度快了将近18倍
    关于用数组替换List,现在就去试验下
    明天加分结帖,回帖重质不重量