public class BlockingQueueTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.printf("Enter base directory(e.g. /usr/local/jdk5.0/src):");
String directory = in.nextLine();
System.out.print("Enter keyword(e.g volatile):");
String keywords = in.nextLine();
final int FILE_QUEUE_SIZE = 10;
final int SEARCH_THREADS = 100;
BlockingQueue<File> queue = new ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
FileEnumerationTask enumerator = new FileEnumerationTask(queue, new File(directory));
new Thread(enumerator).start();
for (int i = 1; i <= SEARCH_THREADS; i++) {
new Thread(new SearchTask(queue, keywords)).start();
}
}
}
/**
* 这个任务枚举所有目录中的文件及其子目录
*/
public class FileEnumerationTask implements Runnable{
public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
this.queue = queue;
this.startingDirectory = startingDirectory;
}
public void run() {
try {
enumerate(startingDirectory);
queue.put(DUMMY);
} catch (InterruptedException e) {
}
}
/**
* 递归地列举了在一个给定的的目录中的所有文件和其子目录
* @param directory 开始目录
* @throws InterruptedException
*/
public void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
enumerate(file);
} else {
queue.put(file);
}
}
}
public static File DUMMY = new File("");
private BlockingQueue<File> queue;
private File startingDirectory;
}
/**
* 这个任务对于一个给定的关键字搜索文件
*/
public class SearchTask implements Runnable {
public SearchTask(BlockingQueue<File> queue, String keyword) {
this.queue = queue;
this.keyword = keyword;
}
public void run() {
try {
boolean done = false;
while (!done) {
File file = queue.take();
if (file == FileEnumerationTask.DUMMY) {
queue.put(file);
done = true;
} else {
search(file);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 搜索特定关键字的文件和打印所有匹配的行
* @param file
* @throws IOException
*/
public void search(File file) throws IOException {
Scanner in = new Scanner(new FileInputStream(file));
int lineNumber = 0;
while (in.hasNextLine()) {
lineNumber++;
String line = in.nextLine();
if (line.contains(keyword)) {
System.out.printf("%s:%d:%s%n", file.getPath(), lineNumber, line);
}
}
in.close();
}
private BlockingQueue<File> queue;
private String keyword;
}