利用RMI技术对远程文件夹进行控制

一、引言

1.实验目的

可以增加文件(文本文件)、修改文件(文本文件)、删除文件、列出文件;统计该文件夹具有多少个文件、占用磁盘空间的总大小;可以给出关键词,检索与该关键词相关的所有文件夹和文件。

2.环境配置

  • 操作系统:Windows 10 X64
  • 编程工具:Intellij IDEA

二、具体过程

1.准备阶段

(1)新建Java项目:File->New->Project

在这里插入图片描述

(2)点击Next

在这里插入图片描述

(3)点击Next

在这里插入图片描述

(4)设置项目名称以及项目存储位置,点击Finish

在这里插入图片描述

2.代码步骤

(1)远程接口定义

定义用于远程对象的接口 FileService。这个接口定义了客户机能够远程地调用的方法。远程接口和本地接口的主要差异在于,远程方法必须能抛出 RemoteException。具体方法如下:
FileService.java:

import java.rmi.RemoteException;
import java.rmi.Remote;
import java.util.List;

public interface FileService extends Remote{
    //列出文件
    public String[] play() throws RemoteException;

    //增加文件
    public boolean addFile(String name) throws RemoteException;

    //删除文件
    public boolean deleteFile(String name) throws RemoteException;

    //修改文件
    public boolean alterFile(String name,String content) throws RemoteException;

    //读取文件内容
    public String readFile(String name) throws RemoteException;

    //统计文件信息
    public long[] fileInformation() throws RemoteException;

    //检索关键字文件
    public List<String> findFile(String keyword) throws RemoteException;
}

(2)实现远程接口

编写一个实现FileService接口的类 FileServiceImpl。
FileServiceImpl.java:

import java.io.*;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

public class FileServiceImpl extends UnicastRemoteObject implements FileService{
    public FileServiceImpl() throws RemoteException {
        super();
    }

    // 列出文件
    @Override
    public String[] play() throws RemoteException {
        File file = new File("G://RMI");
        String[] names=file.list();
        return names;
    }

    // 增加文件
    @Override
    public boolean addFile(String name) throws RemoteException {
        File file = new File("G://RMI",name);
        if(!file.exists()){
            try{
                file.createNewFile();
                return true;
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        return false;
    }

    // 删除文件
    @Override
    public boolean deleteFile(String name) throws RemoteException {
        File file = new File("G://RMI",name);
        if(file.exists()){
            file.delete();
            return true;
        }
        return false;
    }

    // 修改文件
    @Override
    public boolean alterFile(String name, String content) throws RemoteException {
        FileWriter fw = null;

        try{
            fw = new FileWriter("G://RMI/"+name);
        }catch(IOException e1){
            e1.printStackTrace();
        }

        try{
            fw.write(content,0,content.length());
        }catch (IOException e2){
            e2.printStackTrace();
        }

        //关闭流
        try{
            fw.close();
            return true;
        }catch (IOException e3){
            e3.printStackTrace();
        }

        return false;
    }

    //读取文件内容
    @Override
    public String readFile(String name) throws RemoteException {
        FileReader fr = null;

        try{
            fr = new FileReader("G://RMI/"+name);
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }

        int ch = 0;
        String filecontent = "";
        try{
            while((ch = fr.read())!=-1){
                filecontent = filecontent + (char)ch;
            }
        }catch (IOException e){
            e.printStackTrace();
        }

        //
        try{
            fr.close();
        }catch (Exception e){
            e.printStackTrace();
        }

        return filecontent;
    }

    //统计该文件夹具有多少个文件、占用磁盘空间的总大小
    @Override
    public long[] fileInformation() throws RemoteException {
        File file = new File("G://RMI");
        File[] files = file.listFiles();
        long number = files.length;
        long size = 0;
        for(int i=0;i<number;i++){
            size = size + files[i].length()/1024;
        }
        long[] information = {number,size};
        return information;
    }

    // 检索与该关键词相关的所有文件夹和文件
    @Override
    public List<String> findFile(String keyword) throws RemoteException {
        File file = new File("G://RMI");
        String[] names=file.list();
        List<String> result = new ArrayList<>();
        for(int i = 0;i<names.length;i++){
            if(names[i].toLowerCase().contains(keyword)){
                result.add(names[i]);
            }
        }
        return result;
    }
}

(3) 编写服务端程序 Server.java:

创建服务器对象的初始实例,然后将对象的名称写到RMI命名注册表。

//创建服务器对象实例
FileService fileService = new FileServiceImpl();
//注册服务的端口
LocateRegistry.createRegistry(3333);
//绑定本地地址和服务器的路径
Naming.rebind("rmi://192.168.88.176:3333/FileService",fileService);

RMI命名注册表允许您将URL名称分配给对象以便客户机查找它们。要注册名称,需要调用在Naming类上定义的静态rebind方法。这个方法接受对象的URL名称以及对象引用。

名称字符串包含 rmi:// 前缀、运行RMI对象的服务器的计算机主机名和对象本身的名称。这里用了本机地址192.168.88.176。

完整代码如下:
Server.java:

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class Server {
    public Server(){}

    public static void main(String[] args){

        try{
            //创建服务器对象实例
            FileService fileService = new FileServiceImpl();
            //注册服务的端口
            LocateRegistry.createRegistry(3333);
            //绑定本地地址和服务器的路径
            Naming.rebind("rmi://192.168.88.176:3333/FileService",fileService);
            System.out.println("开始服务!");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

(4)编写客户端程序 Client.java。

使用RMI注册表查找远程对象。

//调用远程对象,RMI路径与接口必须与服务器配置一致
FileService fileService = (FileService) Naming.lookup("rmi://192.168.88.176:3333/FileService");

根据选择的操作,调用有远程接口定义的方法。完整代码如下:
Client.java:

import java.rmi.Naming;
import java.util.List;
import java.util.Scanner;

public class Client {
    public Client(){}

    public static void main(String[] args){
        try{
            //调用远程对象,RMI路径与接口必须与服务器配置一致
            FileService fileService = (FileService) Naming.lookup("rmi://192.168.88.176:3333/FileService");

            int choose;
            Scanner input = new Scanner(System.in);

            System.out.println("1.列出文件");
            System.out.println("2.增加文件");
            System.out.println("3.修改文件");
            System.out.println("4.删除文件");
            System.out.println("5.统计文件");
            System.out.println("6.检索关键字查找文件");

            while(true){
                System.out.println("请选择要进行的操作:");
                choose = input.nextInt();
                if(choose == 1){
                    String[] filename = fileService.play();
                    for(int i = 0;i < filename.length;i++){
                        System.out.println(filename[i]);
                    }
                }
                else if(choose == 2){
                    System.out.println("请输入要新增文件的名称:");
                    String name = input.next();
                    boolean flag = fileService.addFile(name);
                    if(flag == true){
                        System.out.println("创建成功!");
                    }
                    else{
                        System.out.println("创建失败!");
                    }
                }
                else if(choose == 3){
                    System.out.println("请输入要修改文件的名称:");
                    String name = input.next();
                    String filecontent = fileService.readFile(name);
                    System.out.println(filecontent);
                    System.out.println("请输入修改内容:");
                    String content = input.next();
                    boolean flag = fileService.alterFile(name,content);
                    if(flag == true){
                        System.out.println("修改成功!");
                    }
                    else{
                        System.out.println("修改失败!");
                    }
                }
                else if(choose == 4){
                    System.out.println("请输入要删除文件的名称:");
                    String name = input.next();
                    boolean flag = fileService.deleteFile(name);
                    if(flag == true){
                        System.out.println("删除成功!");
                    }
                    else{
                        System.out.println("删除失败!");
                    }
                }
                else if(choose == 5){
                    long[] information = fileService.fileInformation();
                    System.out.println("总共有文件夹:"+information[0]+"个.");
                    System.out.println("大小总计:"+information[1]+"KB.");
                }
                else if(choose == 6){
                    System.out.println("请输入要检索的关键字信息:");
                    String keyword = input.next();
                    List<String> filename = fileService.findFile(keyword);
                    for(int i = 0;i < filename.size();i++){
                        System.out.println(filename.get(i));
                    }
                }
                else{
                    System.out.println("无效操作!");
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

三、运行过程

1. 打开Server.java,点击绿色三角运行。

在这里插入图片描述

运行结果:

在这里插入图片描述

2. 打开Client.java,点击绿色三角运行,同上。

运行结果:

在这里插入图片描述
输入1,显示所有文件:
在这里插入图片描述
输入2,新增文件;输入文件名:
在这里插入图片描述
输入3,修改文件;输入文件名:
在这里插入图片描述
输入4,删除文件;输入文件名:
在这里插入图片描述
输入5,显示文件个数和所占磁盘大小:
在这里插入图片描述
输入6,按关键字检索相关文件和文件夹:
在这里插入图片描述

四、总结

在本次实验中有一些问题需要注意,在远程接口定义中,定义的这些方法必须能抛出RemoteException,如果客户机和服务器之间的通信错误,则客户机将捕获此异常。并且该接口本身继承了java.rmi包中定义的Remote接口。Remote接口本身没有定义方法,但通过继承它,我们说明该接口可以被远程地调用。在FileService接口的实现类中,在对文件进行读写操作后必须关闭用close()函数关闭流,不然可能会影响到delete操作,导致不能删除文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值