tail -f 的实现

Java 代码实现 tail -f Java 利用定时实现 tail -f 功能 RandomAccessFile 可以指定位置读,指定位置写。 getFilePointer():获取当前文件的记录指针位置 seek(long pos):把记录指针移动 pos 处 构造方法: RandomAccessFile raf = new RandomAccessFile(File file, String mode); mode 取值:... 阅读详情
最原始的想法和实现

    最容易想到的就是不断的读取一个文件,如果读取到文件结尾(EOF),那么sleep一下然后再次尝试。

    事实上Apache Common IO里就有一个这样的实现

    这种方法到优点是简单而且不需要任何操作系统或者文件系统的支持(跨平台是不会有任何问题),缺点就是如果sleep过长,那么tail -f的结果不是很及时,如果太短,可能浪费到cpu和io很多

    改进的思路很自然,就像io那样,从最原始的cpu轮询到中断的思路。

    就像中断需要更多的硬件支持一样,改进版的tail也需要更多操作系统和文件系统到支持。

网上的相关资料
  1.     GNU coreutils里的实现,也是我们在Linux里用到到命令,其实我们经常用到的命令实现起来也是不容易到,tail.c有两千多行代码。
  2.     JavaEye里INotify的介绍 ,主要是inotify-tools这个工具到介绍,使用这个工具可以实现shell脚本监视文件系统的变化
  3.    Inotify的介绍 ,里面有简洁的示例代码,我后面用c实现的copy了这里到代码。
  4.     http://jnotify.sourceforge.net/  jni实现的跨平台的文件系统监控库,支持win32/64 Linux 和 Mac os(我只测试了Linux,不过它有其它系统到动态链接库文件)
  5.     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 <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <linux/inotify.h>
#include <errno.h>

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<Path> ev = (WatchEvent<Path>)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;
		    }
		}
	}

}



还在手敲LaTeX公式?用Rime小狼毫打造你的专属数学输入法(附完整配置包) 本文介绍如何利用Rime小狼毫输入法引擎打造专属数学公式输入方案,显著提升LaTeX公式输入效率。通过详细配置教程和智能补全技巧,帮助科研人员和学生实现3-5倍的输入速度提升,特别适合学术写作和技术文档创作场景。 阅读详情

相关推荐

【软件逆向】带壳带反调试找flag教程(VMProtect3.0+X64dbg+ScyllaHide)

【软件逆向】带壳带反调试找flag教程(VMProtect 3.0+X64dbg+ScyllaHide)

zhangjiuding的博客 7508

linux下c语言实现tail -f功能---实时读取变化文件中的增量内容

最近由于项目需要,需要对文件中实时新增的数据进行处理,结合tail -f的逻辑,用c语言实现了这一功能,代码如下: [cpp] view plain copy   #include    #include    #include    #include          #define FILE_LINE_LEN 1024 

gredn的专栏 5424

西门子PLC新手必看:200SMART与1200/1500的MODBUS RTU通讯实战(附完整配置流程)

本文详细解析了西门子PLC中S7-200 SMART与S7-1200/1500之间实现MODBUS RTU通讯的完整实战流程。内容涵盖硬件接线、软件配置及程序编写,重点讲解了200SMART作为从站、1200/1500作为主站的典型架构,并提供了关键功能块的使用方法和常见问题排查技巧,帮助新手快速打通不同系列PLC间的数据交换。

weixin_29214559的博客 393

实现Linux tail -f功能

循环 这个比较好像,不停的去读文件,读到就打印出来 f = open('a','r') print(f.read(),end='') while True: try: print(f.read(),end='') except KeyboardInterrupt: f.close() break CPU占用100%,不是一个...

李余通的博客 5512

手把手教你用CCS v7.3调试TI DSP28377:从连接仿真器到看懂Flash里的秘密

本文详细介绍了使用CCS v7.3调试TI DSP28377的全过程,从连接仿真器到解析Flash启动机制。通过实战演示和关键配置要点,帮助工程师快速掌握DSP调试技巧,并深入探讨bootloader设计与在线升级的实现方法,提升开发效率。

weixin_29158413的博客 407

ChatGPT Web转API工具:原理、部署与集成实战

在AI应用开发中,API(应用程序编程接口)是实现系统间通信和数据交换的核心技术,它通过标准化的请求响应机制,将复杂功能封装为可编程的服务。其工作原理基于HTTP协议,通过定义清晰的端点、方法和数据格式,使不同平台的应用能够高效集成AI能力。这一技术价值在于极大降低了开发门槛,促进了自动化流程和智能功能的快速落地,广泛应用于智能客服、内容生成和创意辅助等场景。本文聚焦于如何通过浏览器自动化技术,将ChatGPT的Web界面能力转化为标准API服务,其中涉及Playwright无头浏览器操作和会话Cookie

weixin_42533910的博客 1758

php tail f,PHP实现linux命令tail -f详解

PHP实现linux命令tail -f今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令 tail -f ,这里就来分析实现下。这个想一想也挺简单,通过一个循环检测文件,看文件的大小是否有变化,如果有变化,输出文件变化的部分,当然了这里面会有好多的细节,这里具体分析下。如果初始文件太大或者改变内容太多这个时候一下输出好多内容可能看不清,因此我这里设置了一个阈值 8192 ,...

weixin_39963744的博客 151

[CARLA系列--01]CARLA 0.9.15 在Windows下的安装教程(一)

Carla是一款开源的自动驾驶仿真器,它基本可以用来帮助训练自动驾驶的所有模块,包括感知系统,Localization, 规划系统等等.Carla这个产品目前已经更新到了最新的0.9.15版本,目前遇到好多人在windows系统上如何安装可编辑版的Carla遇到了好多问题,所以针对在windows上的安装,推出此列教程.

汽车ECU自动化测试 4650

php tail f,PHP实现linux命令tail -f

PHP实现linux命令tail -f今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令 tail -f ,这里就来分析实现下。这个想一想也挺简单,通过一个循环检测文件,看文件的大小是否有变化,如果有变化,输出文件变化的部分,当然了这里面会有好多的细节,这里具体分析下。如果初始文件太大或者改变内容太多这个时候一下输出好多内容可能看不清,因此我这里设置了一个阈值 8192 ,...

weixin_30445963的博客 165

2025年CSP-X初赛真题及答案解析(江西)(完善程序第1题)

2025年CSP-X初赛真题及答案解析(江西)(完善程序第1题)

王老师青少年编程 713

【SCADA】KingSCADA将数据插入SQLServer的方法

1、创建数据库及数据表格;2、配置ODBC数据源。3、通过KingSCADA与数据库建立连接,将数据写入数据库对应表格。

做有价值的事,积累有价值的笔记! 4958

python 自动化运维之tail -f 实现

python 自动化运维之tail -f 实现一、基础准备二、基于seek实现类似Linux命令tail -f的功能;代码实现--哆啦A梦的任意门 一、基础准备 (1)通过read方法传输参数,如read(3),当文件打开方式为文本模式时,代表读取3个字符,当文件打开方式为二进制模式时,代表读取3个字节。 (2)以字节为单位定位,如seek、tell等方法。其中seek有3种移动方式:0、1、2,其中1和2必须在二进制模式下进行,但无论哪种模式,都是以bytes为单位移动的。f.tell()返回文件对象当前

AMimiDou_212 1660

Redhawk:什么是timing window?

STA timing file中timing window的作用和计算方式

m0_61544122的博客 1万+

java实现tail,unix / linux“tail -f”的Java IO实现

I'm wondering what techniques and/or library to use to implement the functionality of the linux command "tail -f ". I'm essentially looking for a drop in add-on/replacement for java.io.FileReader. C...

weixin_33514140的博客 231

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

windows 实现 linux tail -f 的效果

windows 实现 linux tail -f 的效果

qq_45841851的博客 1192

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

php 实现 tail -f的功能

php 实现 tail -f的功能 #!/usr/local/php/bin/php <?php if (2 != count($argv)) { fwrite( STDERR, "调用格式错误!使用格式 ./tail filename".PHP_EOL ); return 1; } $file_name = $argv[1]; ...

qq_22640823的博客 800

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

python实现tail -f 功能

这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的pyinotify模块专门监听文件变化,不过我更想介绍的,是解决的思路,毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不在于监控文件增量,而在于怎么打印最后面10行 希望大家读这篇文章前,对python基础、处理文...

weixin_30892987的博客 256

python实现tail -f功能

这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的pyinotify模块专门监听文件变化,不过我更想介绍的,是解决的思路,毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不在于监控文件增量,而在于怎么打印最后面10行 希望大家读这篇文章前,对python基础、处理文...

weixin_30550081的博客 144

PHP实现linux命令tail -f

PHP实现linux命令tail -f 今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令tail -f,这里就来分析实现下。 这个想一想也挺简单,通过一个循环检测文件,看文件的大小是否有变化,如果有变化,输出文件变化的部分,当然了这里面会有好多的细节,这里具体分析下。 如果初始文件太大或者改变内容太多 这个时候一下输出好多内容可能看不清,因此我这里设置了一个阈值8192,...

weixin_30496431的博客 119

python 打印换行_python实现tail -f 功能

希望大家读这篇文章前,对python基础、处理文件和常用模块有一个简单的了解,知道下面几个名词是啥下面思路限于我个人知识,免不了有错误和考虑不周的,希望大家有更好的方法提出来,我随时优化代码,题目的感觉没啥太多的坑,下面让天真烂漫的蜗牛教大家用python的思路怎么用python实现其实思路也不难啦打开这个文件,指针移到最后每隔一秒就尝试readline一下,有内容就打印出来,没内容就sleep大...

weixin_39926042的博客 644

实现类似tail -f file功能

python版本py3 tail -f file是打印最后10行,然后跟踪文件追加的内容打印出来。 python3 以为本方式打开的话,不能回退(f.seek(-1,1)),所有以'rb'方式打开文件。 思路是f.seek(-n,2)从文件末尾回退n字节,然后f.readlines()读取文件,如果读到的少于10行,则再往前移动n字节,直到读到11行,然后打印出来,再跟踪打印文件追加的内容,...

weixin_33834679的博客 373

[笔记]在 PowerShell 中实现 tail -f 命令追踪日志

但由于现在的开发环境是 Window 10 ,并没有 tail 命令,经过查找,发现可以在 PowerShell 下使用。在开发过程中经常会遇到在 Linux 下使用。命令实时追踪日志输出。

永远相信美好的事情即将发生 5292

如何实现Linux下高亮关键字的tail -f功能

公司内部一哥们发布到邮件列表中的一个小tip,挺有意思,属于程序员的“奇淫技巧”类吧,值得记录一下。 如果你在linux下工作,那用tail -f跟踪一个日志文件的输出内容应该是家常便饭了。 但是,有时你更关心的是一些敏感字词,希望能够在动态跟踪的同时,把这些字词高亮出来,比如日志中的ERROR关键字。 那么,一种思路就是把你tail输出的东西再做一次包装处理,这个很符合linux管道处理...

笨小孩的专栏 1785
上一篇: ssh localhost without password
下一篇: Java的Lock小结
fancyerII
博客等级 码龄23年 48粉丝 164原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值