日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java tail -f 后返回_tail -f 的实现 | 学步园

發布時間:2024/10/12 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java tail -f 后返回_tail -f 的实现 | 学步园 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最原始的想法和實現

最容易想到的就是不斷的讀取一個文件,如果讀取到文件結尾(EOF),那么sleep一下然后再次嘗試。

事實上Apache Common IO里就有一個這樣的實現

這種方法到優點是簡單而且不需要任何操作系統或者文件系統的支持(跨平臺是不會有任何問題),缺點就是如果sleep過長,那么tail -f的結果不是很及時,如果太短,可能浪費到cpu和io很多

改進的思路很自然,就像io那樣,從最原始的cpu輪詢到中斷的思路。

就像中斷需要更多的硬件支持一樣,改進版的tail也需要更多操作系統和文件系統到支持。

網上的相關資料

GNU?coreutils里的實現,也是我們在Linux里用到到命令,其實我們經常用到的命令實現起來也是不容易到,tail.c有兩千多行代碼。

JavaEye里INotify的介紹?,主要是inotify-tools這個工具到介紹,使用這個工具可以實現shell腳本監視文件系統的變化

Inotify的介紹?,里面有簡潔的示例代碼,我后面用c實現的copy了這里到代碼。

http://jnotify.sourceforge.net/? jni實現的跨平臺的文件系統監控庫,支持win32/64 Linux 和 Mac os(我只測試了Linux,不過它有其它系統到動態鏈接庫文件)

Java 7的nio.2?,里面提供了監控目錄的api,不過它好像只支持目錄的監控,如果要監控文件,需要遍歷目錄的事件

Linux下的C實現

主要參考了Inotify的介紹,GNU coreutils到代碼太長了,沒細看

核心代碼就3行: fd = inotify_init();

wd = inotify_add_watch(fd, argv1, IN_MODIFY);

read(fd, buffer, 1024);

#include

#include

#include

#include

#include

int main(int argc, char** argv) {

char buffer[1024];

int ch;

long curFilePointer;

int fp;

int fd;

int wd;

if(argc!=2){

printf("usage: tail file-path.\n");

return EXIT_FAILURE;

}

fp=fopen(argv[1],"r");

if(fp<0){

printf("can't open %s\n", argv[1]);

return EXIT_FAILURE;

}

fd = inotify_init();

if (fd < 0) {

printf("Fail to initialize inotify.\n");

return EXIT_FAILURE;

}

wd = inotify_add_watch(fd, argv[1], IN_MODIFY);

if (wd < 0) {

printf("Can't add watch for %s.\n", argv[1]);

return EXIT_FAILURE;

}

while(1){

while ((ch=fgetc(fp))!=EOF){

putchar(ch);

curFilePointer++;

}

read(fd, buffer, 1024);

}

return EXIT_SUCCESS;

}

JNotify測試

下載zip解壓后有個jar包和本地的dll,比如linux就是libJnotify.so

package test;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import net.contentobjects.jnotify.JNotify;

import net.contentobjects.jnotify.JNotifyException;

import net.contentobjects.jnotify.JNotifyListener;

public class JavaTail {

/**

* @param args

* @throws JNotifyException

* @throws InterruptedException

* @throws FileNotFoundException

*/

public static void main(String[] args) throws JNotifyException, IOException, InterruptedException {

if(args.length!=1){

System.err.println("Usage: test.JavaTail filePath!");

return;

}

int mask = JNotify.FILE_MODIFIED;

int watchID = JNotify.addWatch(args[0], mask, false, (JNotifyListener) new Listener(args[0]));

Thread.sleep(Long.MAX_VALUE);

}

}

class Listener implements JNotifyListener {

FileReader fr = null;

public Listener(String filePath) throws IOException{

fr=new FileReader(filePath);

int ch = 0;

while((ch=fr.read())!=-1){

System.out.print((char)ch);

}

}

public void fileRenamed(int wd, String rootPath, String oldName,

String newName) {

}

public void fileModified(int wd, String rootPath, String name) {

int ch = 0;

try {

while((ch=fr.read())!=-1){

System.out.print((char)ch);

}

} catch (IOException e) {

e.printStackTrace();

}

}

public void fileDeleted(int wd, String rootPath, String name) {

}

public void fileCreated(int wd, String rootPath, String name) {

}

}

Java7 NIO.2的實現

可以看到只能監控目錄到事件,然后變歷,判斷是不是我們關注到某個文件。

package test;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

import java.nio.file.FileSystems;

import java.nio.file.Path;

import java.nio.file.StandardWatchEventKinds;

import java.nio.file.WatchEvent;

import java.nio.file.WatchKey;

import java.nio.file.WatchService;

public class JavaTail {

/**

* @param args

* @throws IOException

* @throws InterruptedException

*/

public static void main(String[] args) throws IOException, InterruptedException {

if(args.length!=1){

System.err.println("Usage: test.JavaTail filePath!");

return;

}

File file=new File(args[0]);

FileReader fr=new FileReader(file);

int ch = 0;

while((ch=fr.read())!=-1){

System.out.print((char)ch);

}

File parent=file.getParentFile();

Path filePath=file.toPath();

Path dir=parent.toPath();

WatchService watcher = FileSystems.getDefault().newWatchService();

WatchKey key=dir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);

while(true){

key=watcher.take();

for (WatchEvent> event: key.pollEvents()) {

WatchEvent.Kind> kind = event.kind();

if (kind ==StandardWatchEventKinds.ENTRY_MODIFY){

WatchEvent ev = (WatchEvent)event;

Path filename = ev.context();

Path child = dir.resolve(filename);

if(child.equals(filePath)){

while((ch=fr.read())!=-1){

System.out.print((char)ch);

}

}

}

}

if(!key.reset()){

System.err.println("key.reset() return false");

break;

}

}

}

}

總結

以上是生活随笔為你收集整理的java tail -f 后返回_tail -f 的实现 | 学步园的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。