遠(yuǎn)程過程調(diào)用詳細(xì)教程


一期犬、前言


實(shí)驗(yàn)?zāi)康?/h5>

利用RMI技術(shù)對(duì)遠(yuǎn)程文件夾進(jìn)行控制:可以增加文件(文本文件)、修改文件(文本文件)避诽、刪除文件、列出文件璃谨;統(tǒng)計(jì)該文件夾具有多少個(gè)文件沙庐、占用磁盤空間的總大小。

開發(fā)環(huán)境
  1. 操作系統(tǒng):Windows 10 X64
  2. IDE:Intellij IDEA

二佳吞、準(zhǔn)備

新建Java項(xiàng)目:File->New->Project



點(diǎn)擊Next:



點(diǎn)擊Next:

設(shè)置項(xiàng)目名稱以及項(xiàng)目存儲(chǔ)位置拱雏,點(diǎn)擊Finish:


三、代碼步驟


1. 遠(yuǎn)程接口定義

定義用于遠(yuǎn)程對(duì)象的接口 FileService底扳。這個(gè)接口定義了客戶機(jī)能夠遠(yuǎn)程地調(diào)用的方法铸抑。遠(yuǎn)程接口和本地接口的主要差異在于,遠(yuǎn)程方法必須能拋出 RemoteException衷模。具體方法如下:
FileService.java:

import java.rmi.Remote;
import java.rmi.RemoteException;

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;

    //讀取文件內(nèi)容
    public String readFile(String name) throws RemoteException;

    //統(tǒng)計(jì)文件信息
    public long[] fileInformation() throws RemoteException;
}

這些方法必須能拋出RemoteException鹊汛,如果客戶機(jī)和服務(wù)器之間的通信錯(cuò)誤,則客戶機(jī)將捕獲此異常阱冶。

注:該接口本身繼承了java.rmi包中定義的Remote接口刁憋。Remote接口本身沒有定義方法,但通過繼承它木蹬,我們說明該接口可以被遠(yuǎn)程地調(diào)用至耻。

2. 實(shí)現(xiàn)遠(yuǎn)程接口

編寫一個(gè)實(shí)現(xiàn)FileService接口的類 FileServiceImpl。
FileServiceImpl.java:

import java.io.*;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * 繼承自UnicastRemoteObject,為遠(yuǎn)程對(duì)象的實(shí)現(xiàn)類
 */
public class FileServiceImpl extends UnicastRemoteObject implements FileService{

    public FileServiceImpl() throws RemoteException {
        super();
    }

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

    // 增加文件
    @Override
    public boolean addFile(String name) throws RemoteException {
        File file = new File("D://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("D://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("D://RMI/"+name);
        }catch(IOException e1){
            e1.printStackTrace();
        }

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

        //關(guān)閉流
        try{
            fw.close();
            return true;
        }catch (IOException e3){
            e3.printStackTrace();
        }

        return false;
    }

    //讀取文件內(nèi)容
    @Override
    public String readFile(String name) throws RemoteException {
        FileReader fr = null;

        try{
            fr = new FileReader("D://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;
    }

    //統(tǒng)計(jì)該文件夾具有多少個(gè)文件镊叁、占用磁盤空間的總大小
    @Override
    public long[] fileInformation() throws RemoteException {
        File file = new File("D://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;
    }
}

注:在對(duì)文件進(jìn)行讀寫操作后必須關(guān)閉用close()函數(shù)關(guān)閉流尘颓,不然可能會(huì)影響到delete操作,導(dǎo)致不能刪除文件晦譬。

3. 編寫在服務(wù)器上運(yùn)行的主程序 Server.java疤苹。

創(chuàng)建服務(wù)器對(duì)象的初始實(shí)例,然后將對(duì)象的名稱寫到RMI命名注冊(cè)表蛔添。

//創(chuàng)建服務(wù)器對(duì)象實(shí)例
FileService fileService = new FileServiceImpl();
 //注冊(cè)服務(wù)的端口
LocateRegistry.createRegistry(6600);
//綁定本地地址和服務(wù)器的路徑
Naming.rebind("rmi://127.0.0.1:6600/FileService",fileService);

RMI命名注冊(cè)表允許您將URL名稱分配給對(duì)象以便客戶機(jī)查找它們痰催。要注冊(cè)名稱兜辞,需要調(diào)用在Naming類上定義的靜態(tài)rebind方法。這個(gè)方法接受對(duì)象的URL名稱以及對(duì)象引用夸溶。

名稱字符串包含 rmi:// 前綴逸吵、運(yùn)行RMI對(duì)象的服務(wù)器的計(jì)算機(jī)主機(jī)名和對(duì)象本身的名稱。這里用了本機(jī)地址127.0.0.1缝裁。

完整代碼如下:
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();
                //注冊(cè)服務(wù)的端口
                LocateRegistry.createRegistry(6600);
                //綁定本地地址和服務(wù)器的路徑
                Naming.rebind("rmi://192.168.1.102:6600/FileService",fileService);
                System.out.println("開始服務(wù)扫皱!");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
}
4. 編寫客戶端程序 Client.java。

使用RMI注冊(cè)表查找遠(yuǎn)程對(duì)象捷绑。

//調(diào)用遠(yuǎn)程對(duì)象韩脑,RMI路徑與接口必須與服務(wù)器配置一致
FileService fileService = (FileService)Naming.lookup("rmi://127.0.0.1:6600/FileService");

根據(jù)選擇的操作,調(diào)用有遠(yuǎn)程接口定義的方法粹污。完整代碼如下:
Client.java:

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

public class Client {

    public Client(){}

    public static void main(String[] args){
        try{
            //調(diào)用遠(yuǎn)程對(duì)象段多,RMI路徑與接口必須與服務(wù)器配置一致
            FileService fileService = (FileService)Naming.lookup("rmi://127.0.0.1:6600/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.統(tǒng)計(jì)文件");

            while(true){
                System.out.println("請(qǐng)選擇要進(jìn)行的操作:");
                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("請(qǐng)輸入要新增文件的名稱:");
                    String name = input.next();
                    boolean flag = fileService.addFile(name);
                    if(flag == true){
                        System.out.println("創(chuàng)建成功!");
                    }
                    else{
                        System.out.println("創(chuàng)建失斪撤浴进苍!");
                    }
                }
                else if(choose == 3){
                    System.out.println("請(qǐng)輸入要修改文件的名稱:");
                    String name = input.next();
                    String filecontent = fileService.readFile(name);
                    System.out.println(filecontent);
                    System.out.println("請(qǐng)輸入修改內(nèi)容:");
                    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("請(qǐng)輸入要?jiǎng)h除文件的名稱:");
                    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]+"個(gè).");
                    System.out.println("大小總計(jì):"+information[1]+"KB.");
                }
                else{
                    System.out.println("無(wú)效操作!");
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

四宋下、運(yùn)行

1. 打開Server.java嗡善,點(diǎn)擊Run,選擇Run,在彈出框中選擇Server学歧。


運(yùn)行結(jié)果:
2. 打開Client.java滤奈,點(diǎn)擊Run,選擇Run,在彈出框中選擇Client撩满。同上蜒程。
運(yùn)行結(jié)果:

輸入1,顯示所有文件:



輸入2伺帘,新增文件昭躺;輸入文件名:



輸入3,修改文件伪嫁;輸入文件名:

輸入4领炫,刪除文件;輸入文件名:

輸入5张咳,顯示文件個(gè)數(shù)和所占磁盤大械酆椤:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末似舵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子葱峡,更是在濱河造成了極大的恐慌砚哗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰奕,死亡現(xiàn)場(chǎng)離奇詭異蛛芥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)军援,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門仅淑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人胸哥,你說我怎么就攤上這事涯竟。” “怎么了空厌?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵昆禽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蝇庭,道長(zhǎng),這世上最難降的妖魔是什么捡硅? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任哮内,我火速辦了婚禮,結(jié)果婚禮上壮韭,老公的妹妹穿的比我還像新娘北发。我一直安慰自己,他們只是感情好喷屋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布琳拨。 她就那樣靜靜地躺著,像睡著了一般屯曹。 火紅的嫁衣襯著肌膚如雪狱庇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天恶耽,我揣著相機(jī)與錄音密任,去河邊找鬼。 笑死偷俭,一個(gè)胖子當(dāng)著我的面吹牛浪讳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涌萤,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼淹遵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼口猜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起透揣,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤济炎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后淌实,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冻辩,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年拆祈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恨闪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡放坏,死狀恐怖咙咽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淤年,我是刑警寧澤钧敞,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站麸粮,受9級(jí)特大地震影響溉苛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弄诲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一愚战、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧齐遵,春花似錦寂玲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至伶授,卻和暖如春断序,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糜烹。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工逢倍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人景图。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓较雕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子亮蒋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • JAVA面試題 1扣典、作用域public,private,protected,以及不寫時(shí)的區(qū)別答:區(qū)別如下:作用域 ...
    JA尐白閱讀 1,154評(píng)論 1 0
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 4,592評(píng)論 1 114
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,103評(píng)論 1 32
  • JAVA相關(guān)基礎(chǔ)知識(shí) 1慎玖、面向?qū)ο蟮奶卣饔心男┓矫?1.抽象: 抽象就是忽略一個(gè)主題中與當(dāng)前目標(biāo)無(wú)關(guān)的那些方面贮尖,以...
    yangkg閱讀 665評(píng)論 0 1
  • 錯(cuò)誤信息提示如下: Failed to parse Date value '2018-10-31 13:04:16...
    良人與我閱讀 1,149評(píng)論 1 2