多个计算机之间触发事件,相互通信的一种方法----通过文件的办法

1.概述

所谓通过文件实现多台计算机的通信,是指计算机之间通过共享一个文件,在一台电脑上修改文件,另外一台电脑实时监控这个文件,如果发现修改就打开文件阅读其中的内容,从而实现计算机之间信息的传达。

2.具体做法(以java为例)

2.1.阅读文件(用于读取信息)

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		    String pathname = "C:\\Users\\yyzhang\\Desktop\\test\\state1.txt"; // 绝对路径或相对路径都可以,写入文件时演示相对路径,读取以上路径的input.txt文件
	        //防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw;
	        //不关闭文件会导致资源的泄露,读写文件都同理
	        //Java7的try-with-resources可以优雅关闭文件,异常时自动关闭文件;详细解读https://stackoverflow.com/a/12665271
	        try (FileReader reader = new FileReader(pathname);
	             BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
	        ) {
	            String line;
	            //网友推荐更加简洁的写法
	            while ((line = br.readLine()) != null) {
	                // 一次读入一行数据
	            	String s=line;
	            	System.out.println(s);
	                System.out.println(line);
	            }
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	
	

}

运行结果
在这里插入图片描述

2.2.写入文件(用于写入信息)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class WriteFile {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		    String pathname = "C:\\Users\\yyzhang\\Desktop\\test\\state.txt"; // 绝对路径或相对路径都可以,写入文件时演示相对路径,读取以上路径的input.txt文件
	        //防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw;
	        //不关闭文件会导致资源的泄露,读写文件都同理
	        //Java7的try-with-resources可以优雅关闭文件,异常时自动关闭文件;详细解读https://stackoverflow.com/a/12665271
		    File writename = new File(pathname); // 相对路径,如果没有则要建立一个新的output。txt文件
			//writename.createNewFile(); // 创建新文件
			BufferedWriter out = new BufferedWriter(new FileWriter(writename));
			out.write("我会写入文件啦\r\nhaha"); // \r\n即为换行
			out.flush(); // 把缓存区内容压入文件
			out.close(); // 最后记得关闭文件
			} 
	    }

这里写入的是事先写好的字符串,实际中肯定会传入字符串。

2.3.实时监控文件(用于发现改变)

Java 1.7开始,java提供了一个文件监控的办法WatchService,WatchService 用来观察被注册了的对象的变化和事件。它和Watchable两个接口的配合使用, WatchService类似于在观察者模式中的观察者,Watchable类似域观察者模式中的被观察者。

而Java 7中的java.nio.file.Path类就实现了Watchable接口,这样的话,和Path类一起可实现观察者模式。

2.3.1.基本使用

要使用WatchService,首先必须创建一个实例,使用 java.nio.file.FileSystems 类:

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

接下来,我们初始化一个被监控文件夹的Path类:

Path path = Paths.get("pathToDir");

然后,将这个Path注册到 WatchService 中去:

WatchKey watchKey = path.register(
  watchService, StandardWatchEventKinds...);

注意,注册方法第二个参数是一个可变长参数,也就是可以注册多个事件类型。
StandardWatchEventKinds 有如下四种类型:

  1. ENTRY_CREATE 创建事件,可是新建一个文件或重命名文件
  2. ENTRY_MODIFY 修改事件,文件内容被修改,有些系统上面文件属性被修改也会触发
  3. ENTRY_DELETE 删除事件,文件被删除或被重命名
  4. OVERFLOW 如果丢失或放弃事件时被触发,我们一般不会关注这个类型

2.3.2.WatchKey

WatchKey 类代表了这个监听服务的注册,可以用它来获取事件的各个属性。一般来讲我们会通过如下方法获取这个类实例:

WatchKey watchKey = watchService.take();

这个方法会一直阻塞,知道某个事件到来。

有一点非常重要的需要记住,一旦 WatchKey 实例通过poll或take返回后,它再也不会捕获任何事件,触发你调用reset方法:

watchKey.reset();

这样的话就能将这个 WatchKey 又放回到watch service队列中去,可以重新等待新的事件了。

所以一般来讲这个服务代码形式会写成如下形式:

WatchKey key;
while ((key = watchService.take()) != null) {
    for (WatchEvent<?> event : key.pollEvents()) {
        //process
    }
    key.reset();
}

解释一下运行过程,take()方法会一直阻塞直到返回一个WatchKey实例,然后进入循环内部, pollEvents()方法会返回当前Key上面所有事件列表,我们一个个去处理这些事件。

所有事件处理完成后,必须调用reset方法,让这个key重新进入监听队列。

2.3.3.实例

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

//单线程
public class DirectoryWatcherExample {
	 
    public static void main(String[] args) throws IOException, InterruptedException {
        WatchService watchService
          = FileSystems.getDefault().newWatchService();
 
        Path path = Paths.get("C:\\Users\\weishuo\\Desktop\\test");
 
        path.register(
          watchService, 
            StandardWatchEventKinds.ENTRY_CREATE, 
              StandardWatchEventKinds.ENTRY_DELETE, 
                StandardWatchEventKinds.ENTRY_MODIFY);
 
        WatchKey key;
        while ((key = watchService.take()) != null) {
        	String change = "";
            for (WatchEvent<?> event : key.pollEvents()) {
                System.out.println(
                  "Event kind:" + event.kind() 
                    + ". File affected: " + event.context() + ".");
                change=change+"Event kind:" + event.kind() 
                + ". File affected: " + event.context();
            }
            if(change.contains("ENTRY_MODIFY")&&change.contains("state1.txt"))
            	System.out.println("发现变化了");
            key.reset();
        }
    }
}

运行结果
在这里插入图片描述

2.4.同步

电脑连接在一个局域网内,推荐使用自同步这个软件
在这里插入图片描述
若是需要通过网络传送,则可能得需要自己写一个通信的发送接收代码

3.参考文献

https://www.xncoding.com/2017/09/21/java/watchservice.html
https://my.oschina.net/u/566591/blog/1620377
https://blog.csdn.net/monkeyduck/article/details/11525771

4.问题提出

不知有人是否可以提出别的建议或者办法????感觉一直检查文件挺耗费cpu资源。有想法可以评论交流呀。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值