public static void main(String[] args) throws Exception{

List<String> urlList = new ArrayList<String>();

urlList.add("/BTS_HX/ HTTP/1.1"); 
urlList.add("/BTS_HX/index.jsp HTTP/1.1"); 
urlList.add("/BTS_HX/flight.jsp HTTP/1.1"); 
urlList.add("/BTSHotel_HX/ HTTP/1.1"); 
urlList.add("/BTSHotel_HX/menu.jsp HTTP/1.1"); 
urlList.add("/BTS_HX/signup.do?method=init HTTP/1.1");  FileInputStream fis = new FileInputStream("d:\\Logs\\access_log");
//得到 文件通道
FileChannel fc = fis.getChannel(); ByteBuffer bf = ByteBuffer.allocate(102400);

String temp = "";
String str = "";
List<String> list = new ArrayList<String>();

File file = new File("d:\\abc");
BufferedWriter outFile = new BufferedWriter(new FileWriter(file, true));

while (fc.read(bf) != -1){
bf.flip();
while(bf.hasRemaining()){
str = String.valueOf((char)bf.get());
// System.out.print((char)bf.get());
if(!str.equals("\n")){
temp += str;
}else{
list.add(temp);
temp = "";
}
}
bf.clear();
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
for(int j=0;j<urlList.size();j++){
if(list.get(i).indexOf(urlList.get(j))>=0){
outFile.write(list.get(i) + "\n");
}
}
}
outFile.close();
System.out.println("List中有字符串:"+list.size()+"个!");
list.clear();
}
fc.close();如上所示程序:其要达到的目的是从文件d:\\Logs\\access_log中一行一行读出日志,如果那一条日志包含urlList中所示的字符串,将其写出到另外一个d:\\abc的文件。现在这个代码的问题是如果日志比较小,则会写出abc文件,但少了一行,而我要读的文件大概有1.8G大,如此一来则不能写出abc文件了。还有,如果access_log文件中有6条日志,则下面的两层FOR循环会写出36条日志到abc文件中,请各位帮忙修改,谢谢啦!最好帮我改进代码。

解决方案 »

  1.   

    日志内容如下:
    30.16.18.11 - - [01/Dec/2009:15:47:19 +0800] "GET /BTS_HX/index.jsp HTTP/1.1" 200 27652
    30.16.18.11 - - [01/Dec/2009:15:47:31 +0800] "GET /BTS_HX/ HTTP/1.1" 200 27652
    30.16.18.11 - - [01/Dec/2009:15:47:53 +0800] "GET /BTS_HX/index.jsp HTTP/1.1" 200 27652
    30.16.18.11 - - [01/Dec/2009:15:47:58 +0800] "GET /BTS_HX/signup.do?method=init HTTP/1.1" 200 26725
    30.16.18.11 - - [01/Dec/2009:15:48:01 +0800] "GET /BTS_HX/flight.jsp HTTP/1.1" 200 12292
    30.16.18.11 - - [01/Dec/2009:15:48:06 +0800] "GET /BTS_HX/index.jsp HTTP/1.1" 200 27652
      

  2.   

    for(int i=0;i<list.size();i++){
                    System.out.println(list.get(i));
                    for(int j=0;j<urlList.size();j++){
                        if(list.get(i).indexOf(urlList.get(j))>=0){
                            outFile.write(list.get(i) + "\n");
                        }
                    }
                }
    可以用list.contains代替吧,不就是查这行有没有List里面的内容么?
      

  3.   

    list.contains 方法是判断那个第一个list中的一条记录是否再第二个list中存在,而我的情况是urlList里存放的是一个“/BTSHotel_HX/menu.jsp HTTP/1.1”的字符串,而list中放的是“30.16.18.11 - - [01/Dec/2009:15:47:58 +0800] "GET /BTS_HX/signup.do?method=init HTTP/1.1" 200 26725
    ” 的字符串,这个方法好像不能用呀
      

  4.   

    哦,没看清。
    你要判断
    30.16.18.11 - - [01/Dec/2009:15:47:58 +0800] "GET /BTS_HX/signup.do?method=init HTTP/1.1这句话是否包含urlList中的任何一个条目是吧?
      

  5.   

    那似乎对urlList进行遍历就在所难免了。
    但你都读出来在循环是有点问题的。
      

  6.   

    如果读取的源文件太大,推荐用bufferedReader,一部分一部分的读在内存里