搜索文本內容——Java代碼的簡單實現(修改版)

原文:http://blog.csdn.net/newjueqi/article/details/4210495

【文章標題】搜索文本內容——Java代碼的簡單實現(修改版)

【文章作者】曾健生

【作者郵箱】[email protected]

【作者QQ】190678908

【作者博客】http://blog.csdn.net/newjueqi

【編程環境】JDK 1.6.0_01

【作者聲明】歡迎轉載文章,但轉載請保留文章的完整性以及註明文章的出處。

 

*******************************************************************************

       昨天由於編程的要求,需要從300多個源代碼中查找一個關鍵字在哪個源代碼文件中用過,逼於無奈只能一個文件一個文件的查找,結果30分鐘後本人就崩潰了(連續查了200多個文件),看到眼睛都花了還是沒結果。這時我是多麼懷念平時上網用搜索引擎的日子!突然間靈機一動,現在從衆多的源碼文件中查找一個關鍵字,不就是一個典型的搜索行爲,現在學習完Java的IO流後就實現一個文本內容搜索軟件。

       本人這個文本搜索軟件的思路很簡單,分爲以下幾步:

1.       遍歷一個目錄裏的每個文件對象

2.       如果文件對象是一個目錄,則通過遞歸繼續遍歷這個目錄下的每個文件

3.       如果文件對象是一個文件,則判斷文件名是否以“.java”結尾(是否Java源文件),如果以“.java”結尾,則讀取文本內容。

4.       把文本的每一行存儲在一個字符串中,通過contains函數判斷該行字符串是否包含關鍵字,如果包含關鍵字就把該行字符串信息寫入到一個配置文件中

5.       關閉文件流。

 

 

package newjueqi.NET.csdn.SearchText;

 

import java.io.*;

 

//山寨版的LineNumberReader類,讀取文本內容時可獲得當前的代碼行數,實現了Java中的LineNumberReader的功能

class MyLineNumberReader

{

    //這裏用的是裝飾器模式,具體的內容可參見本人的博文《打造山寨產品和僞造產品的利器——裝飾模式》 

    private Reader fr;

    private int lineNumber=0;   //記錄當前的行數

   

   

    MyLineNumberReader( Reader fr )

    {

       this.fr=fr;

    }

   

    /*

    通過read()函數一個一個字符的讀取,當遇到回車換行就返回讀取的一行字符串

    */

    public String readLine()

    {

       int num=0;

       StringBuffer sb=new StringBuffer();

       try {

           while( (num=fr.read())!=-1 )

           {

              if( num=='/r')

                  continue;

              else if( num=='/n')

              {

                  lineNumber++; //讀取一行,行號加1

                  return sb.toString(); //返回讀取的一行字符串

              }

              else

              {

                  sb.append((char)num );

              }

           }

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

           return null;

       }

      

       //防止文本末尾沒加回車換行符,以丟失文本內容

       if( sb.length()>0 )

       {

           lineNumber++;

           return sb.toString();

       }

       return null;

    }

   

    //關閉輸入流對象

    public void close()

    {

       try {

           fr.close();

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

   

    //設置當前的行數

    public void setLineNumber(int lineNumber)

    {

       this.lineNumber=lineNumber;

    }

   

    //獲取當前的行數

    public int getLineNumber()

    {

       return lineNumber;

    }

}

 

/*

搜索文本內容的類

輸入的內容爲要查找的目錄和查找的內容

*/

class SearchContent

{

    private File f=null;     //要查找的目錄對象

    private String filename=null;   //要查找的目錄路徑

    private BufferedWriter bw=null;   

    private String findtxt=null;    //要查找的文本內容

    private String fileType=null;   //要查找的文件類型

    private int totalFileCount=0;   //共搜索的文件數

    private int findedFileCount=0;  //搜索到有用的文件數

    private int findContentCount=0; //搜索到的有用信息數目

   

   

    /**構造函數,

    @param f 要查找目錄的對象

    @param findtxt    要查找的關鍵字

    @param fileType 要查找的文件類型

    */

    SearchContent( String  filename ,String findtxt, String fileType )

    {

       this.filename=filename;

       this.findtxt=findtxt;

       this.fileType=fileType;

    }

   

    //暴露的公共接口,開始在指定的目錄中搜索關鍵字

    public void startSearchContent()

    {     

       try

       {

           bw=new BufferedWriter(

                  new FileWriter( "log.txt"));

          

           f=new File( filename );

          

           //搜索關鍵字的內容

           listFile( f );

      

           //顯示文件的統計信息

           showInfo();

      

           //關閉文件流

           bw.close();

          

           System.out.println( "搜索完畢,搜索結果已保存在log.txt文件中" );

       }

       catch( Exception e)

       {

           System.out.println( "搜索出錯!!!" );

       }

      

    }

   

    /*

    通過遞歸搜索目錄,搜索過程分兩種情況:

    1.如果是目錄,則通過遞歸繼續查找目錄下的文件

    2.如果是文件,則先判斷是否是fileType類型文件,如果是的話就搜索文件內容

    */

    private void listFile( File f )

    {     

       File[] files = f.listFiles();

       for(int x=0; x<files.length; x++)

       {

           if(files[x].isDirectory())

              listFile( files[x] );

           else

           {

              //判斷文件名是否以fileType結尾

              if( files[x].getName().endsWith( fileType ))

              {

                  FindTxt( files[x]);

              }

           }

       }

    }

   

    /*

    從文件中搜索制定的內容,分下面幾步

    1.使用自定義的山寨版LineNumberReader類,讀取文件的每一行

    2.

    */

    private void FindTxt(File f )

    {

       totalFileCount++; //搜索到的文件數加1

       boolean flag=false;  //記錄當前文件中是否搜索到關鍵字的標誌

      

       MyLineNumberReader br=null;

       try {

           br = new MyLineNumberReader(

              new FileReader(f));

           String s=null;

           while( (s=br.readLine())!=null)

           {

              //文本行中是否包含制定的字符串

              if(s.contains(findtxt))

              {

                  flag=true//搜索到文件的關鍵字,標誌變爲真

                  findContentCount++;  //搜到的關鍵字相當的數目加1

                  bw.write(f.getAbsolutePath());

                  bw.newLine();

                  bw.write("  "+br.getLineNumber()+":  "+s );

                  bw.newLine();

                  bw.newLine();

                 

              }

           }

       } catch (FileNotFoundException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

      

       //如果當前文件中搜索到關鍵字,則把搜索到的有用文件數加1

       if(  flag==true )

       {

           findedFileCount++;  

       }

      

       br.close();

    }

   

    //輸出搜索的統計信息

    private void showInfo() throws IOException

    {

       bw.write( "        搜索關鍵字:"+findtxt);

       bw.newLine();

       bw.write( "        共搜索的.java文件數:"+totalFileCount);

       bw.newLine();

       bw.write( "        關鍵文件數:"+findedFileCount);

       bw.newLine();

       bw.write( "        搜索到的關鍵字數目:"+findContentCount );

       bw.newLine();

    }

      

   

}

 

輸出結果如下:

d:/day4/Demo5.java
  4:   int age;

d:/day4/Demo5.java
  21:    p.age = 23;

d:/day4/Demo5.java
  25:    System.out.println(p.age);

d:/day4/Demo5.java
  33:    p.age = 25; 

d:/day4/Demo6.java
  12:   private int age;

d:/day4/Demo6.java
  25:   public void setAge(int myage)

d:/day4/Demo6.java
  27:    age = myage;

d:/day4/Demo6.java
  31:    return age;

        搜索關鍵字:age
        共搜索的.java文件數:10
        關鍵文件數:2
        搜索到的關鍵字數目:8

最後感嘆一句:使用親手寫的軟件果然很爽很痛快!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章