利用java-RMI进行大文件传输

  为什么要用RMI​

  在这次的项目中,对于客户端与服务器之间的通信,想了许多办法,由于做的是富客户端应用,最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写,但使用比较方便,反观java-sockets,虽然比较灵活,但需要自己规定服务器端和客户端之间的通信协议。比较麻烦,几经权衡,最终还是选择RMI来进行服务器-客户端通信

文件上传问题

  在使用java-rmi的过程中,必然会遇到一个文件上传的问题,由于在rmi中无法传输文件流(比如rmi中的方法参数不能是FileInputStream之类的),那么我们只好选择一种折中的办法,就是先用FileInputStream将文件读到一个Byte数组中,然后把这个Byte数组作为参数传进RMI的方法中,然后在服务器端将Byte数组还原为outputStream,这样就能通过RMI来传输文件了

  这样做也有缺点,就是无法检验传输过来的数据的准确性,汗。。。

  下面我就一个实例来讲解一下

文件结构

  

  FileClient

  packagermiupload;  importjava.io.BufferedInputStream;  importjava.io.File;  importjava.io.FileInputStream;  importjava.io.FileNotFoundException;  importjava.io.IOException;  importjava.net.MalformedURLException;  importjava.rmi.Naming;  importjava.rmi.NotBoundException;  importjava.rmi.RemoteException;  publicclassFileClient{  publicFileClient(){  //TODOAuto-generatedconstructorstub  }  publicstaticvoidmain(String[]args){  try{  FileDataServicefileDataService=(FileDataService)Naming.lookup("rmi://localhost:9001/FileDataService");  fileDataService.upload("/Users/NeverDie/Documents/test.mp4",newFileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));  }catch(MalformedURLException|RemoteException|NotBoundExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }  }  //这个方法比较重要,通过这个方法把一个名为filename的文件转化为一个byte数组  privatebyte[]fileToByte(Stringfilename){  byte[]b=null;  try{  Filefile=newFile(filename);  b=newbyte[(int)file.length()];  BufferedInputStreamis=newBufferedInputStream(newFileInputStream(file));  is.read(b);  }catch(FileNotFoundExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }catch(IOExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }  returnb;  }  }

  FileDataService

  packagermiupload;  importjava.net.URL;  importjava.rmi.Remote;  importjava.rmi.RemoteException;  publicinterfaceFileDataServiceextendsRemote{  //这里的filename应该是该文件存放在服务器端的地址  publicvoidupload(Stringfilename,byte[]file)throwsRemoteException;  }

  FileDataService_imp

  packagermiupload;  importjava.io.BufferedOutputStream;  importjava.io.File;  importjava.io.FileNotFoundException;  importjava.io.FileOutputStream;  importjava.io.IOException;  importjava.net.URL;  importjava.rmi.RemoteException;  importjava.rmi.server.RMIClientSocketFactory;  importjava.rmi.server.RMIServerSocketFactory;  importjava.rmi.server.UnicastRemoteObject;  publicclassFileDataService_impextendsUnicastRemoteObjectimplementsFileDataService{  publicFileDataService_imp()throwsRemoteException{  }  @Override  publicvoidupload(Stringfilename,byte[]fileContent)throwsRemoteException{  Filefile=newFile(filename);  try{  if(!file.exists())  file.createNewFile();  BufferedOutputStreamos=newBufferedOutputStream(newFileOutputStream(file));  os.write(fileContent);  }catch(FileNotFoundExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }catch(IOExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }  ;}  }

  FileServer

  packagermiupload;  importjava.net.MalformedURLException;  importjava.rmi.Naming;  importjava.rmi.RemoteException;  importjava.rmi.registry.LocateRegistry;  publicclassFileServer{  FileDataServicefileDataService;  publicFileServer(){  try{  fileDataService=newFileDataService_imp();  LocateRegistry.createRegistry(9001);  Naming.rebind("rmi://localhost:9001/FileDataService",fileDataService);  }catch(RemoteExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }catch(MalformedURLExceptione){  //TODOAuto-generatedcatchblock  e.printStackTrace();  }  }  /**  *@paramargs  */  publicstaticvoidmain(String[]args){  newFileServer();  }  }

也不要说曾经失去,失去的不是永远失去,得到的不是永远拥有,

利用java-RMI进行大文件传输

相关文章:

你感兴趣的文章:

标签云: