Linux进程管理器

linux平台上,使用java语言编写的任务管理器
源码地址

工作原理

在子进程里执行linux的shell命令,获取输出流,从输出流中解析数据,从而得到进程信息,实现管理进程任务。

用到的知识点

java Process对象

Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序)。
Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。

Shell命令

要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而 ps 命令就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多 的资源等等。总之大部分信息都是可以通过执行该命令得到的。
下面是本程序用到的Shell命令:
1、ps -aux –sort=-%cpu
(显示所有进程,按CPU占用率由高到低排序)
2、ps -aux
(显示所有进程)
3、kill -9 [PID]
(按PID来强制杀死进程)
(ps命令非常强大,感兴趣的朋友可以自行百度)

java Swing

用到的控件:
1. JTable
2. JButton
3. JTabbedPane
4. JPanel
5. JProgressBar

代码部分

ShellCmd类,用来保存所有使用到的Shell命令

package com.manager;

/**
 * Shell命令枚举类
 * Created by zf on 2017/4/6.
 */
public enum ShellCmd {
    SHOW_ALL_TASK("ps -aux --sort=-%cpu"),
    SHOW_RUNNING_TASK("ps -aux"),
    KILL_SELECT_TASK("kill -9 "),
    SHOW_DYNAMIC_TREE("top");


    private String cmd;

    ShellCmd(String cmd) {
        this.cmd = cmd;
    }

    public String getCmd() {
        return cmd;
    }
}

ShellExec类,用于执行Shell命令

package com.manager;

import com.dto.RawDataAnalyse;

import java.io.*;
import java.util.Vector;

/**
 * Shell命令执行类
 * Created by zf on 2017/4/6.
 */
public class ShellExec {

    private static boolean CLOSE_AFTER_EXEC = false;//执行完成后是否关闭终端
    private static Vector> data = null;

    private static ShellExec INSTANCE;
    public static ShellExec getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new ShellExec();
        }
        return INSTANCE;
    }

    public static Vector> getData() {
        return data;
    }

    private ShellExec() {
    }

    public void showAllTask(boolean close_after_exec) {
        CLOSE_AFTER_EXEC = close_after_exec;
        Process pro = null;
        try {
            pro = Runtime.getRuntime().exec(ShellCmd.SHOW_ALL_TASK.getCmd());
            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            RawDataAnalyse rawDataAnalyse = new RawDataAnalyse(br);
            data = rawDataAnalyse.fromAllTaskCMD2Tasks();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (CLOSE_AFTER_EXEC && pro != null && pro.isAlive()) {
                pro.destroy();
            }
        }
    }

    public void showRunningTask(boolean close_after_exec) {
        CLOSE_AFTER_EXEC = close_after_exec;
        Process pro = null;
        try {
            pro = Runtime.getRuntime().exec(ShellCmd.SHOW_RUNNING_TASK.getCmd());
            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            RawDataAnalyse rawDataAnalyse = new RawDataAnalyse(br);
            data = rawDataAnalyse.fromRunningTaskCMD2Tasks();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (CLOSE_AFTER_EXEC && pro != null && pro.isAlive()) {
                pro.destroy();
            }
        }
    }

    public void showDynamicTree(boolean close_after_exec) {
        CLOSE_AFTER_EXEC = close_after_exec;
        Process pro = null;
        try {
            pro = Runtime.getRuntime().exec(ShellCmd.SHOW_DYNAMIC_TREE.getCmd());


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (CLOSE_AFTER_EXEC && pro != null && pro.isAlive()) {
                pro.destroy();
            }
        }
    }

    public void kill(int PID, boolean close_after_exec) {
        CLOSE_AFTER_EXEC = close_after_exec;
        String cmd = ShellCmd.KILL_SELECT_TASK.getCmd() + PID;
        Process pro = null;
        try {
            pro = Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (CLOSE_AFTER_EXEC && pro != null && pro.isAlive()) {
                pro.destroy();
            }
        }
    }

}

RawDataAnalyse类,用于解析从输入流中读取到的原始数据

package com.dto;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * 原始数据解析类
 * 构造参数:带缓冲区的输入流br
 * Created by zf on 2017/4/7.
 */
public class RawDataAnalyse {
    private BufferedReader br = null;

    public RawDataAnalyse(BufferedReader br) {
        this.br = br;
    }

    /*
    * 解析数据
    * 数据来源:执行查看所有任务命令后得到的数据
    * */
    public Vector> fromAllTaskCMD2Tasks() {
        Vector> result = new Vector<>();
        String firstLine;
        String line;
        try {
            firstLine = br.readLine();//剔除第一行
            while ((line = br.readLine()) != null) {
                String[] arr = line.split("\\s+");//按空格符来分割字符串
                if (arr.length >= 11) {
                    Task task = new Task();
                    task.setUSER(arr[0]);
                    task.setPID(Integer.parseInt(arr[1]));
                    task.setCPU(Double.parseDouble(arr[2]));
                    task.setMEM(Double.parseDouble(arr[3]));
                    task.setVSZ(Integer.parseInt(arr[4]));
                    task.setRSS(Integer.parseInt(arr[5]));
                    task.setTTY(arr[6]);
                    task.setSTAT(arr[7]);
                    task.setSTART(arr[8]);
                    task.setTIME(arr[9]);
                    int num = arr.length;
                    String command = "";
                    for (int i = 10; i < num; i++) {
                        command = command + arr[i].toString();
                    }
                    task.setCOMMAND(command);
                    result.add(task.format2ArrayData());
                } else {
                    System.out.println("字符串分割出错!");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public Vector> fromRunningTaskCMD2Tasks() {
        Vector> result = new Vector<>();
        String firstLine;
        String line;
        try {
            firstLine = br.readLine();//剔除第一行
            while ((line = br.readLine()) != null) {
                String[] arr = line.split("\\s+");//按空格符来分割字符串
                if (arr.length >= 11) {
                    Task task = new Task();
                    task.setUSER(arr[0]);
                    task.setPID(Integer.parseInt(arr[1]));
                    task.setCPU(Double.parseDouble(arr[2]));
                    if (task.getCPU() != 0) {
                        task.setMEM(Double.parseDouble(arr[3]));
                        task.setVSZ(Integer.parseInt(arr[4]));
                        task.setRSS(Integer.parseInt(arr[5]));
                        task.setTTY(arr[6]);
                        task.setSTAT(arr[7]);
                        task.setSTART(arr[8]);
                        task.setTIME(arr[9]);
                        int num = arr.length;
                        String command = "";
                        for (int i = 10; i < num; i++) {
                            command = command + arr[i].toString();
                        }
                        task.setCOMMAND(command);
                        result.add(task.format2ArrayData());
                    }
                } else {
                    System.out.println("字符串分割出错!");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

}

Task类,进程对象类,用于实例化每一个进程

package com.dto;

import java.util.Vector;

/**
 * linux进程对象类
 * 必须包含的属性:PID
 * Created by zf on 2017/4/7.
 */
public class Task {
    private int PID;//进程ID                 1
    private String COMMAND;//实际指令        2
    /*
    * D 无法中断的休眠状态(通常 IO 的进程);
    * R 正在运行可中在队列中可过行的;
    * S 处于休眠状态;
    * T 停止或被追踪;
    * W 进入内存交换(从内核2.6开始无效);
    * X 死掉的进程(从来没见过);
    * Z 僵尸进程;
    * */
    private String STAT;//进程状态           3
    private double CPU;//cup占用率           4
    private double MEM;//物理内存占用率       5
    private String USER;//用户名             6
    private int VSZ;//虚拟内存使用量          7
    private int RSS;//固定内存使用量          8
    private String TTY;//关联的终端          9
    private String START;//启动的时间        10
    private String TIME;//占用CPU的时间      11
    private Vector vector;

    public String getUSER() {
        return USER;
    }

    public void setUSER(String USER) {
        this.USER = USER;
    }

    public int getPID() {
        return PID;
    }

    public void setPID(int PID) {
        this.PID = PID;
    }

    public double getCPU() {
        return CPU;
    }

    public void setCPU(double CPU) {
        this.CPU = CPU;
    }

    public double getMEM() {
        return MEM;
    }

    public void setMEM(double MEM) {
        this.MEM = MEM;
    }

    public int getVSZ() {
        return VSZ;
    }

    public void setVSZ(int VSZ) {
        this.VSZ = VSZ;
    }

    public int getRSS() {
        return RSS;
    }

    public void setRSS(int RSS) {
        this.RSS = RSS;
    }

    public String getTTY() {
        return TTY;
    }

    public void setTTY(String TTY) {
        this.TTY = TTY;
    }

    public String getSTART() {
        return START;
    }

    public void setSTART(String START) {
        this.START = START;
    }

    public String getTIME() {
        return TIME;
    }

    public void setTIME(String TIME) {
        this.TIME = TIME;
    }

    public String getCOMMAND() {
        return COMMAND;
    }

    public void setCOMMAND(String COMMAND) {
        this.COMMAND = COMMAND;
    }

    public String getSTAT() {
        return STAT;
    }

    public void setSTAT(String STAT) {
        this.STAT = STAT;
    }

    public Vector format2ArrayData() {
        vector = new Vector<>();
        vector.add(PID);
        vector.add(COMMAND);
        vector.add(STAT);
        vector.add(CPU);
        vector.add(MEM);
        vector.add(USER);
        vector.add(VSZ);
        vector.add(RSS);
        vector.add(TTY);
        vector.add(START);
        vector.add(TIME);
        return vector;
    }
}
 
  

以上是关键代码,数据解析完成后,会放入TableModel,然后插入表控件中,显示给用户看。
————————————————————————————————————————————
简单的小程序,如果有什么好的的建议或者不懂的地方,欢迎留言。源码已开源到github上,地址在文章开头。
转载请注明出处

http://blog.csdn.net/zf1228

你可能感兴趣的:(课程设计)