📄 logreader.java
字号:
import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.util.Vector;
public class LogReader {
private File filename;//要处理的文件
private LogDealer logdealer;//负责输出数据.
public File getFilename() {
return filename;
}
public void setFilename(File filename) {
this.filename = filename;
}
public LogDealer getLogdealer() {
return logdealer;
}
public void setLogdealer(LogDealer logdealer) {
this.logdealer = logdealer;
}
/**
* 把日志文件映射成内存缓冲
* @param File f日志文件
* @return MappedByteBuffer 内存映射缓冲。
* @throws 考虑异常
* */
private MappedByteBuffer mappedFile2Buffer(File f) throws Exception{
FileInputStream fis=new FileInputStream(f);
FileChannel fc=fis.getChannel();
return fc.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
}
/**
* 读取所有登录日志,并按登入与登出分类放入数据结构
* @param MappedByteBuffer buffer 日志文件的内存缓冲
* Vector<LogRecord> logins 日志的登入数据
* Vector<LogRecord> logouts 日志的登出数据
* @return void
* @throws 考虑异常
* */
private void readLog(MappedByteBuffer buffer,
Vector<LogRecord> logins,Vector<LogRecord> logouts){
int len=buffer.capacity()/372;//记录条数
for(int i=0;i<len;i++){//循环读取数据
buffer.position(i*372);
byte[] busername=new byte[32];
buffer.get(busername);//读取用户名
String username=new String(busername).trim();
if(username.startsWith(".")){continue;}
LogRecord log=new LogRecord();
log.setUsername(username);
buffer.get(new byte[4]);//跳4字节
byte[] bdevice=new byte[32];//读取设备类型
buffer.get(bdevice);
log.setDevice(new String(bdevice).trim());
log.setPid(buffer.getInt());//进程ID
short type=buffer.getShort();//登录类型
buffer.get(new byte[6]);//跳6个字节
log.setVisittime(buffer.getInt());//登录时间
buffer.get(new byte[30]);//跳30字节
byte[] buserip=new byte[257];//客户IP
buffer.get(buserip);
log.setUserip(new String(buserip).trim());
//分类存放到数据结构.
if(type==7){/*登入*/ logins.add(log);}
if(type==8){/*登出*/ logouts.add(log);}
}
buffer.clear();
buffer=null;
}
/**
* 把登录数据按一个登入一个登出匹配成一条完整的登录过程记录。
* @param Vector<LogRecord> logins 日志的登入数据
* Vector<LogRecord> logouts 日志的登出数据
* @return Vector<MatchedRecord> 所有完整的登入/登出记录
* @throws 考虑异常
* */
private Vector<MatchedRecord> match(Vector<LogRecord> logins,Vector<LogRecord> logouts){
Vector<MatchedRecord> re=new Vector<MatchedRecord>();/** 循环匹配查找.找到:就得到匹配数据* 找不到:就表示在线**/
int num=logins.size();
NEXT:for(int i=0;i<num;i++){
LogRecord login=logins.get(0);
MatchedRecord matched=new MatchedRecord();
matched.setUsername(login.getUsername());matched.setDevice(login.getDevice());
matched.setUserip(login.getUserip());matched.setLogintime(login.getVisittime());
for(int j=0;j<logouts.size();j++){
LogRecord logout=logouts.get(j);
if(login.equals(logout)){//匹配
matched.setLogouttime(logout.getVisittime());//匹配成功,则生成一条登录数据
long duration=logout.getVisittime()-login.getVisittime();
int days=(int)(duration/(24*60*60));
duration=(int)(duration-days*(24*60*60));
int hours=(int)(duration/(60*60));
duration=(int)(duration-hours*(60*60));
int minutes=(int)(duration/60);
String sduration="";
if(days>0){sduration+="<+"+days+">";}
DecimalFormat format=new DecimalFormat("00");
sduration+=format.format(hours)+":"+format.format(minutes);
matched.setDuration(sduration);
logouts.remove(logout);/*删除该登出数据*/logins.remove(login);//删除该登入数据
re.add(matched);continue NEXT;}}
matched.setLogouttime(0);//没有匹配成功,表示在线。
matched.setDuration("仍然在登录状态");
logins.remove(login);
re.add(matched);}
return re;
}
/**
* 得到所有的登录历史数据
* @param 无
* @return void
* @throws 考虑异常
* */
public void collect()throws Exception{
MappedByteBuffer buffer=mappedFile2Buffer(filename);
Vector<LogRecord> logins=new Vector<LogRecord>();
Vector<LogRecord> logouts=new Vector<LogRecord>();
readLog(buffer, logins, logouts);
Vector<MatchedRecord> matched=match(logins,logouts);
logdealer.deal(matched);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -