11.2. 发送文件

使用文件传输API,通过现有的MQ网络发送文件到远程服务器,包括以下步骤:

以下代码演示了如何使用文件传输API,通过现有的MQ网络发送文件到远程服务器:

    public static void main(String[] args) throws Exception {
        //创建登陆器对象,在创建对象时指定要登录的服务器的IP地址,端口号,用户名和密码
        //注意:必须将“admin”作为用户名和并提供其密码,因为 AMQ 的文件传输功能目前
        //限制只能由“admin”用户使用。
        IMqLoginer loginer = new JaasLoginerImpl("localhost", 4888, "admin", "admin");
        loginer.login();
        //创建对象工厂,并创建文件发送器对象。
        FileTransporterObjectFactory factory = new FileTransporterObjectFactory(loginer);
        IFileSender sender = factory.createClientFileSender();
        
        //指定文件分成多少块同时进行传输,每一块由一个线程传输。
        int sendingThreadsNum = 5; 
        //指定文件的目的服务器的路由名。
        String destTarget = "RouterB"; 
        //指定文件的备注。
        String remark = "This is a test file."; 
        //指定要发送的文件在本地机器的路径。
        String sendingFilePath = "F:\\jdk-1_5_0_07-windows-i586-p.rar"; 
        //使用以上的参数创建发送信息对象。
        FileSendingInfo info = new FileSendingInfo(sendingThreadsNum, destTarget, remark, sendingFilePath);
        
        //向文件发送器中加入监听器,监听发送器的状态转换。
        sender.addFileSenderListener(new ClientFileSenderListener(sendingFilePath));
        
        //启动一个新的线程,用于接收用户输入取消发送,因为主线程调用send方法之后
        //将会处于阻塞状态。在新启动的线程中调用IFileSender的cancelCurrentSending方法
        //取消发送。
        CancelSendingThread cancelThread = new CancelSendingThread(sender, sendingFilePath);
        cancelThread.start();
        
        //开始发送文件,并得到send返回之后的发送结果,判断发送是否出现异常了。
        //还可以判断文件是否已经发送完毕,假如没有发送完毕可以从发送结果中取得
        //该文件的UUID,下次继续将该文件发送到服务器上的时候需要提供该UUID。
        //假如要继续发送未发送完的文件,这里调用的是continueSend方法,其他过程一样。
        FileSendingResult result = sender.send(info);
        if (result.getSendFileException() != null) {
            throw new Exception("Send file failed.", result.getSendFileException());
        }                     
        
        //登出服务器。
        loginer.logout();
    }

文件发送器的监听器代码:

 
    class ClientFileSenderListener implements IFileSenderListener {
        
        //发送的文件的路径。
        private final String sendingFilePath;
        //打印文件发送进度等信息的线程。
        private PrintSendingStateThread printThread;
        
        private ClientFileSenderListener(String sendingFilePath) {
            this.sendingFilePath = sendingFilePath;
        }
        
       /**
         * 当发送器准备完毕,开始发送文件的时候会调用监听器的该方法。
         * 调用该方法之前,发送器已经处于STATE_SENDING状态。
         * @param sender 
         *               发生该状态变化的发送器。
         */
        public void onAfterSendingStarted(IFileSender sender) {
            //启动打印文件发送状态线程,在线程中调用IFileSender的getCurrentSendingFileSize
            //getFileSendedSize等方法显示文件发送进度等信息。
            this.printThread = new PrintSendingStateThread(sender, sendingFilePath);
            this.printThread.start();
            //进行日志记录等代码
            ...
        }

        /**
         * 当发送器已经停止了发送文件,会调用监听器的该方法。
         * 调用该方法的时候,发送器已经处于STATE_IDLE状态。
         * @param sender 
         *               发生该状态变化的发送器。
         */    
        public void onAfterSendingStoped(IFileSender sender) {
            //停止打印发送状态线程。
            synchronized (this.printThread.getPrintThreadSemaphore()) {
                this.printThread.getPrintThreadSemaphore().notifyAll();
            }
            //进行日志记录等代码
            ...
        }

        /**
         * 当发送器准备停止发送文件,在停止之前会调用监听器的该方法。
         * 调用该方法的时候,发送器还不是处于STATE_IDLE状态。
         * @param sender 
         *               发生该状态变化的发送器。
         */    
        public void onBeforeSendingStoped(IFileSender sender) {
            //可以在该方法中显示文件发送器停止发送之前,总共发送了文件的多少字节
            //发送进度等信息。或者进行日志记录等。
        }
        
    }