最近项目中要求实现远程文件下载,  原先如果被下载文件放在项目应用的 web 路径下那可以通过很多经典的方式去实现,但现在被下载的文件和项目应用不在同一台服务器上, 原来的方式无法实现,因为被下载文件的路径都是以  // ip地址 / 目录1/目录1/ *.*  来表示的, 网上参考了一下, 好象可以用 java  RMI  实现 , 所以写了一个Demo,  客户端和服务端都放在本机(winXP系统)  

(源码见附件  服务端:server.rar 客户端:client.rar) 

1.远程接口  
  FileInterface.java代码如下:  
  import java.rmi.Remote;  
  import java.rmi.RemoteException;  
  public interface FileInterface extends Remote {  
    public byte[] downloadFile(String fileName) throws  
    RemoteException;  
  } 
  
2.实现远程的接口 
    import java.io.*;  
  import java.rmi.*;  
  import java.rmi.server.UnicastRemoteObject;  
  public class FileImpl extends UnicastRemoteObject  
   implements FileInterface {  
    private String name;  
    public FileImpl(String s) throws RemoteException{  
     super();  
     name = s;  
    }  
    public byte[] downloadFile(String fileName){  
     try {  
       File file = new File(fileName);  
       byte buffer[] = new byte[(int)file.length()];  
       BufferedInputStream input = new  
     BufferedInputStream(new FileInputStream(fileName));  
       input.read(buffer,0,buffer.length);  
       input.close();  
       return(buffer);  
     } catch(Exception e){  
     System.out.println("FileImpl: "+e.getMessage());  
       e.printStackTrace();  
       return(null);  
     }}}  

3.编写服务端  
  (1)创建并安装一个RMISecurityManager实例。  
  (2)创建一个远程对象的实例。  
  (3)使用RMI注册工具来注册这个对象。  
  FileServer.java 代码如下:  
  import java.io.*;  
  import java.rmi.*;  
  public class FileServer {  
    public static void main(String argv[]) {  
     if(System.getSecurityManager() == null) {  
  System.setSecurityManager(new RMISecurityManager());  
     }  
     try {  
       FileInterface fi = new FileImpl("FileServer");  
       Naming.rebind("//127.0.0.1/FileServer", fi);  
     } catch(Exception e) {  
       System.out.println("FileServer: "+e.getMessage());  
       e.printStackTrace();  
     }}}  

4.编写客户端  
import java.io.*;  
  import java.rmi.*;  
  public class FileClient{  
    public static void main(String argv[]) {  
     if(argv.length != 2) {  
      System.out.println("Usage: java FileClient fileName machineName");  
      System.exit(0);  
     }  
     try {  
       String name = "//" + argv[1] + "/FileServer";  
       FileInterface fi = (FileInterface) Naming.lookup(name);  
       byte[] filedata = fi.downloadFile(argv[0]);  
       File file = new File(argv[0]);  
       BufferedOutputStream output = new  
  BufferedOutputStream(new FileOutputStream(file.getName()));  
       output.write(filedata,0,filedata.length);  
       output.flush();  
       output.close();  
     } catch(Exception e) {  
       System.err.println("FileServer exception: "+ e.getMessage());  
       e.printStackTrace();  
     }}}  


demo步骤: 

1.     使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:  
         
                     prompt  >  rmiregistry  (此处没写端口,默认使用1099) 

2.     运行服务FileServer  
        
                    prompt  >  java -Djava.security.policy=policy.txt FileServer 
         
 此时不知道为什么老是报拒绝连接的错误,请各位大侠指正,不胜感激 

FileServer: Connection refused to host: 127.0.0.1; nested exception is:  
java.net.ConnectException: Connection refused: connect  
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:  
java.net.ConnectException: Connection refused: connect  
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)  
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 )  
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)  
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)  
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)  
at java.rmi.Naming.rebind(Naming.java:160)  
at FileServer.main(FileServer.java:11)  
Caused by: java.net.ConnectException: Connection refused: connect  
at java.net.PlainSocketImpl.socketConnect(Native Method)  
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)  
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)  
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)  
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)  
at java.net.Socket.connect(Socket.java:516)  
at java.net.Socket.connect(Socket.java:466)  
at java.net.Socket. <init>(Socket.java:366)  
at java.net.Socket. <init>(Socket.java:179)  
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22)  
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128)  
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) ... 6 more