在 linux shell 下经常使用的一个命令组合: grep [-v] “filter” filePath | tail -n needLines,用来查看文件中符合条件的最后 n 行记录,尤其在监控 server 的 log 的时候。
现在有一个需求:从 web 管理后台向 search server 发送一个 stat 命令,查看搜索索引的各项统计信息,其中就包括索引更新,查询的 log 的最后 n 条记录。于是需要在 search server 里实现这样一个功能。
PS:如果是 php,我肯定会选用 exec 一条外部 shell 命令,获取命令的输出 的方式来做,但 java,只好自己动手,重复发明轮子了。
PS2:stl 的 rotate 代码真是太精炼了。有空需要多看看这样的代码,能从中学到很多“ how code talks ”
[code=java]
/**
* implenment: grep [-v] "filter" filePath | tail -n needLines
*
* if filter start with '-', means exclude mode "grep -v", others include mode "grep"
*
* NOTE. filter no regex support for now
*
* @param filePath
* @param needLines
* @param filter
* @return String[] strs
*/
public static String[] tailFromFile(String filePath, int needLines, String filter){
boolean filtermod = (filter != null && filter.length() > 0) ? true : false;
boolean exclusive = (filtermod && filter.startsWith("-")) ? true : false;
if (needLines <= 0 || needLines >= 50){
needLines = 10;
}
String[] strs = new String[needLines];
try {
RandomAccessFile raf = new RandomAccessFile(filePath, "rb");
int point = 0;
String s;
while ((s = raf.readLine()) != null){
if (filtermod){
if (exclusive){
if (s.contains(filter.substring(1))){
continue;
}
}
else {
if (! s.contains(filter)){
continue;
}
}
}
strs[point] = s;
if (++ point >= needLines){
point = 0;
}
}
// need a rotate
if (strs[needLines -1] != null){
// stl rotate algrithm
// see : http://www.cplusplus.com/reference/algorithm/rotate/
int first = 0;
int middle = point;
int last = needLines;
int next = middle;
while (first != next)
{
//swap (*first++,*next++);
s = strs[first];
strs[first] = strs[next];
strs[next] = s;
first += 1;
next += 1;
if (next == last){
next = middle;
}
else if (first == middle){
middle = next;
}
}
}
} catch (Exception e) {
log.warn("read from file error: " + filePath, e);
return null;
}
return strs;
}
[/code]
Post a Comment