利用java-RMI進(jìn)行大文件傳輸
為什么要用RMI
在這次的項(xiàng)目中,對(duì)于客戶端與服務(wù)器之間的通信,想了許多辦法,由于做的是富客戶端應(yīng)用,最終將技術(shù)選定在了RMI和Java-sockets兩種之間,其中RMI的靈活性不高,客戶端和服務(wù)器端都必須是java編寫,但使用比較方便,反觀java-sockets,雖然比較靈活,但需要自己規(guī)定服務(wù)器端和客戶端之間的通信協(xié)議。比較麻煩,幾經(jīng)權(quán)衡,最終還是選擇RMI來進(jìn)行服務(wù)器-客戶端通信
文件上傳問題
在使用java-rmi的過程中,必然會(huì)遇到一個(gè)文件上傳的問題,由于在rmi中無法傳輸文件流(比如rmi中的方法參數(shù)不能是FileInputStream之類的),那么我們只好選擇一種折中的辦法,就是先用FileInputStream將文件讀到一個(gè) Byte數(shù)組中,然后把這個(gè)Byte數(shù)組作為參數(shù)傳進(jìn)RMI的方法中,然后在服務(wù)器端將Byte數(shù)組還原為outputStream,這樣就能通過RMI 來傳輸文件了
這樣做也有缺點(diǎn),就是無法檢驗(yàn)傳輸過來的數(shù)據(jù)的準(zhǔn)確性,汗。。。
下面我就一個(gè)實(shí)例來講解一下
文件結(jié)構(gòu)
FileClient
- package rmiupload;
- import java.io.BufferedInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.rmi.Naming;
- import java.rmi.NotBoundException;
- import java.rmi.RemoteException;
- public class FileClient {
- public FileClient() {
- // TODO Auto-generated constructor stub
- }
- public static void main(String[] args) {
- try {
- FileDataService fileDataService = (FileDataService) Naming.lookup("rmi://localhost:9001/FileDataService");
- fileDataService.upload("/Users/NeverDie/Documents/test.mp4", new FileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));
- } catch (MalformedURLException | RemoteException | NotBoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- //這個(gè)方法比較重要,通過這個(gè)方法把一個(gè)名為filename的文件轉(zhuǎn)化為一個(gè)byte數(shù)組
- private byte[] fileToByte(String filename){
- byte[] b = null;
- try {
- File file = new File(filename);
- b = new byte[(int) file.length()];
- BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
- is.read(b);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return b;
- }
- }
FileDataService
- package rmiupload;
- import java.net.URL;
- import java.rmi.Remote;
- import java.rmi.RemoteException;
- public interface FileDataService extends Remote{
- //這里的filename應(yīng)該是該文件存放在服務(wù)器端的地址
- public void upload(String filename, byte[] file) throws RemoteException;
- }
FileDataService_imp
- package rmiupload;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.net.URL;
- import java.rmi.RemoteException;
- import java.rmi.server.RMIClientSocketFactory;
- import java.rmi.server.RMIServerSocketFactory;
- import java.rmi.server.UnicastRemoteObject;
- public class FileDataService_imp extends UnicastRemoteObject implements FileDataService{
- public FileDataService_imp() throws RemoteException {
- }
- @Override
- public void upload(String filename, byte[] fileContent) throws RemoteException{
- File file = new File(filename);
- try {
- if (!file.exists())
- file.createNewFile();
- BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
- os.write(fileContent);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- ; }
- }
FileServer
- package rmiupload;
- import java.net.MalformedURLException;
- import java.rmi.Naming;
- import java.rmi.RemoteException;
- import java.rmi.registry.LocateRegistry;
- public class FileServer {
- FileDataService fileDataService;
- public FileServer() {
- try {
- fileDataService = new FileDataService_imp();
- LocateRegistry.createRegistry(9001);
- Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (MalformedURLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- new FileServer();
- }
- }