在工作中经常需要在很多文本文件中查找指定的内容.而windows系统中没有linux中提供的强大的文本查找功能。
通常 可以在Jbuilder,EditPlus,UltraEdit等开发工具或文本编辑器里进行多文件查找,
也可以在Winrar里使用查找功能,但是这些工具都有其不够方便的地方,就是没法吧查询到的结果复制保存到文件里,
而且在远程服务器上,通常没有 Jbuilder,EditPlus,UltraEdit这些,用winrar查找是非常繁琐。
于是我写一段java代码来进行查询,并将查询结果记录到文件中。
我用它在远程服务器查找文本话单,也在本地查找 Awstats 的log。
文本查找的代码如下:
FindText.java的代码
[code]
package com.lizongbo;
import java.util.concurrent.*;
import java.io.File;
import java.io.FileFilter;
public class FindText {
private static ThreadPoolExecutor threadPool = null;
private static FileFilter ff = new FileFilter() {
public boolean accept(File pathname) {
String pathl = pathname.getName().toLowerCase();
//只匹配 .txt 和 .log 结尾的文件
if (pathname.isDirectory() ||
pathl.endsWith(".txt") || pathl.endsWith(".log")) {
return true;
}
return false;
}
};
/**
* 在日志文件中按行查找指定的字符串
* 调用命令如: java com.lizongbo.FindHuadan 123456 D:/logdir d:/out/rs.log 10
* @param args String[]
*/
public static void main(String[] args) {
// args = new String[] {
// "618119.com", "D:/Java/apache-tomcat-6.0.14/webapps/awstats/logs/",
// "E:/workdoc/2007/1221/rs.log", "8",
// };
if (args == null || args.length < 2) {
System.out.println(
"请输入日志文件路径和要查找的内容 例如 java com.lizongbo.FindHuadan 12345 d:/logs");
return;
}
String text = args[0];
String root = args[1];
File rsFile = new File("rs.txt"); //默认输出的文件名
int threadnum = 10;
if (args.length >= 3) { //如果指定了查找结果的输出文件名
rsFile = new File(args[2]);
rsFile.getParentFile().mkdirs();
}
if (args.length >= 4) { //如果指定了分配线程的个数
try {
threadnum = Integer.valueOf(args[3]);
}
catch (Exception ex) {
}
}
//初始化线程池
threadPool = new ThreadPoolExecutor(threadnum, threadnum * 2, 6,
TimeUnit.SECONDS,
new ArrayBlockingQueue(1000),
new ThreadPoolExecutor.
DiscardOldestPolicy());
File f = new File(root);
System.out.println("开始进行查找的时间:" + System.currentTimeMillis());
findText(text, f, rsFile);
threadPool.shutdown(); //关闭线程池
}
public static void findText(String text, File f, File rsFile) {
if (f.exists()) {
if (f.isDirectory()) {
for (File fs : f.listFiles(ff)) {
findText(text, fs, rsFile);
}
}
else {
threadPool.execute(new FindTask(text, f, rsFile));
}
}
else {
System.out.println(f + "不存在!");
}
}
}
[/code]
FindTask.java的代码为:
[code]
package com.lizongbo;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.charset.*;
import java.nio.channels.FileLock;
import java.nio.ByteBuffer;
public class FindTask
implements Runnable {
String text = "";
File f = null;
File rs = null;
public FindTask(String text, File f, File rs) {
this.text = text;
this.f = f;
this.rs = rs;
}
public void run() {
try {
boolean isfind = false;
StringBuilder sb = new StringBuilder(800);
sb.append("在文件").append(f.getAbsolutePath())
.append("找到以下内容:").append('\r').append('\n');
java.io.FileInputStream fis = new FileInputStream(f);
java.io.InputStreamReader isr = new InputStreamReader(fis,
Charset.forName("GBK")); //以gbk编码打开文本文件
java.io.BufferedReader br = new BufferedReader(isr, 8192 * 8);
String line = null;
int linenum = 0;
while ( (line = br.readLine()) != null) {//按行读取
linenum++;
if (line.indexOf(text) >= 0) {
isfind = true;
sb.append('第').append(linenum).append("行: ");
sb.append(line).append('\r').append('\n');
System.out.println(f + "当前匹配行: " + line);
}
}
if (isfind) {
java.io.RandomAccessFile rsf = new RandomAccessFile(rs, "rw");
FileChannel fc = rsf.getChannel();
fc.force(true);
FileLock fl = fc.lock();
ByteBuffer bb = ByteBuffer.allocate(sb.length() * 2);
bb.put(sb.toString().getBytes());
bb.flip();
fc.write(bb, rsf.length());
fl.release();
fc.close();
rsf.close();
}
System.out.println(Thread.currentThread().getName() + " 对 " + f +
"处理完毕 at " + System.currentTimeMillis());
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
[/code]