代维的同事排查问题,可能会遇到从成百上千个压缩日志文件(gz格式)中搜索XXX字符串等,
在linux环境,应该可以用管道命令find ./ -name '*.gz' |xargx grep 'xxx'搞定,不过本人更喜欢在window环境下,自己想办法搞定。
于是就自己动手写了这个简易的搜索器(其实对awt和swing都不太熟悉,慢慢研究来的)。
先上个截图,大致的样子就是这样:
搜索某个字符的操作是这样的:
闲话不说了,说说关键代码:
1.需要一个frame,作为顶级窗口显示,所有的东西,都是包括在这个frame中
public void launchFindFrame(){
frame = new Frame("检索字符串");
frame.setSize(520, 360);
frame.setLocation(screenSize.width/3, screenSize.height/3);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
initMenu();
initLayout();
initBar();
frame.setVisible(true);
}
2.需要定义一些button、menu、label等等
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screenSize = tk.getScreenSize();//获取物理屏幕的大小,以便计算弹出frame可以居中
Frame frame = null;
MenuBar mb = new MenuBar();//菜单栏
Menu m1 = new Menu("File");
Menu m2 = new Menu("Help");
MenuItem mi1 = new MenuItem("选择");//菜单下拉项
MenuItem mi2 = new MenuItem("退出");
MenuItem mi3 = new MenuItem("关于帮助");
//文本提示区、按钮
Label lbl1 = new Label("搜索路径:");
Label lbl2 = new Label("搜索内容:");
Label lblPath = new Label("空");
TextField tf = new TextField(20);
Button btn = new Button("搜索");
Button expBtn = new Button("导出搜索结果");
TextArea ta = new TextArea();
Panel innerp = new Panel(new FlowLayout(FlowLayout.LEFT));
//用于大框架布局的3个panel
Panel p1 = new Panel(new BorderLayout());
Panel p2 = new Panel(new FlowLayout(FlowLayout.LEFT));
Panel p3 = new Panel(new BorderLayout());
//进度条相关显示
JProgressBar progressbar = new JProgressBar();
Label barLbl = new Label("玩命搜索中",Label.CENTER);
Button breakBtn = new Button("停止搜索");
Thread findFileExecThread = null;//搜索文件算法类的线程引用
FindFileExecutor ffe = null; //搜索文件算法类
3.给各个按钮加上事件监听
//菜单按钮,选择文件事件监听
mi1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);//既可以是文件也可以是文件夹
int intRetVal = fc.showOpenDialog(frame);
if (intRetVal == JFileChooser.APPROVE_OPTION) {
lblPath.setSize(screenSize.width, lblPath.getHeight());
lblPath.setText(fc.getSelectedFile().getPath());
}
}
});
mi3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "有任何问题请联系chengsheng.wang@zznode.com", "友情提醒",JOptionPane.PLAIN_MESSAGE);
}
});
//搜索按钮的事情监听
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if(lblPath.getText() == null || "".equals(lblPath.getText()) || "空".equals(lblPath.getText())){
JOptionPane.showMessageDialog(null, "搜索路径不能为空!", "提示",JOptionPane.WARNING_MESSAGE);
} else if(tf.getText() == null || "".equals(tf.getText())){
JOptionPane.showMessageDialog(null, "搜索内容不能为空!", "提示",JOptionPane.WARNING_MESSAGE);
} else {
initFindAction();
final Dialog d = new Dialog(frame);
d.setResizable(false);
d.setModal(true);
d.setTitle("进度提示");
d.setBackground(Color.LIGHT_GRAY);
d.setLayout(new BorderLayout());
Panel np = new Panel();
//终止搜索按钮的事情监听,用flag标识让搜索文件的逻辑自动退出,而不是强制interrupt线程,当然你也强制interrupt不了
breakBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if(findFileExecThread != null && findFileExecThread.isAlive()){
ffe.setFlag(true);
}
d.setVisible(false);
d.dispose();
}
});
np.add(breakBtn);
d.add(np,BorderLayout.NORTH);
d.add(barLbl,BorderLayout.CENTER);
d.add(progressbar,BorderLayout.SOUTH);
d.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
d.setVisible(false);
d.dispose();
}
});
d.setBounds(frame.getX()+100, frame.getY()+100,280,120);//设定使其出现位置
//执行搜索算法
ffe = new FindFileExecutor(lblPath.getText(),tf.getText(),progressbar,ta);
findFileExecThread = new Thread(ffe);
findFileExecThread.start();
d.setVisible(true);
}
}
});
//导出搜索结果按钮事件
expBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if(ta.getText() != null && !"".equals(ta.getText())){
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
String name = dateformat.format(new Date()) + ".txt";
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setDialogType(JFileChooser.SAVE_DIALOG);
chooser.setDialogTitle("导出搜索结果");
chooser.setSelectedFile(new File(name));
//过滤只显示和保存txt文件
chooser.addChoosableFileFilter(new FileFilter(){
public boolean accept(File f) {
if (f.getName().endsWith("txt") || f.isDirectory()) {
return true;
}else{
return false;
}
}
public String getDescription() {
return "文本文件(*.txt)";
}
});
int intRetVal = chooser.showSaveDialog(frame);
if (intRetVal == JFileChooser.APPROVE_OPTION) {
if(new File(chooser.getSelectedFile().getPath()).exists()){
int confirmRetVal = JOptionPane.showConfirmDialog(null, "文件已经存在,是否要覆盖该文件?", "确认",JOptionPane.WARNING_MESSAGE);
if(JOptionPane.YES_NO_OPTION != confirmRetVal){
return;
}
}
//导出
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(new File(chooser.getSelectedFile().getPath())));
String[] textAreaLines = ta.getText().trim().split("\r\n");
for(String line : textAreaLines){
bw.write(line);
bw.newLine();
}
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(bw != null){
try {
bw.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
int openRetVal = JOptionPane.showConfirmDialog(null, "导出数据成功,要打开该文件吗?", "确认",JOptionPane.WARNING_MESSAGE);
if(openRetVal == JOptionPane.YES_NO_OPTION){
Desktop d = Desktop.getDesktop();//since jdk1.6 调用系统默认的打开文件功能
try {
d.open(new File(chooser.getSelectedFile().getPath()));
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
} else {
JOptionPane.showMessageDialog(null, "无搜索结果!", "提示",JOptionPane.WARNING_MESSAGE);
}
}
});
4.进度条的初始化
//初始化进度条的事件监听
public void initBar(){
progressbar.setOrientation(JProgressBar.HORIZONTAL);
progressbar.setMinimum(0);
progressbar.setMaximum(100);
progressbar.setValue(0);
progressbar.setStringPainted(true);
progressbar.addChangeListener(new ChangeListener(){
/**
* 每次progressbar.setValue()时,如果value值改变,则触发此监听方法
*/
public void stateChanged(ChangeEvent e) {
int value = progressbar.getValue();
if (e.getSource() == progressbar) {
barLbl.setText("已完成搜索:" + ffe.getCurrentIndex() + "个文件,共发现"+ffe.getMatchCount()+"处匹配记录");
barLbl.setForeground(Color.blue);
}
if(value == progressbar.getMaximum()){
barLbl.setText("终于撸完了,从"+ffe.getTotalOfFiles()+"个文件中撸到"+ffe.getMatchCount()+"个匹配记录!");
breakBtn.setLabel("关闭");
}
}
});
progressbar.setPreferredSize(new Dimension(300, 20));
progressbar.setBorderPainted(true);
progressbar.setBackground(Color.pink);
}
5.搜索文件算法(这个省略,地球人都知道)
代码完成后,用j2ewiz.exe工具把jar包装成exe文件,双击运行。
最后成样:
末尾附上源代码、包装工具以及成品的链接:
http://download.csdn.net/detail/wangchsh2008/8733305
本文仅限交流学习使用,写得很简陋,请见谅!