java使用rmi傳輸大文件示例分享
為什么要用RMI
在這次的項目中,對于客戶端與服務(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的過程中,必然會遇到一個文件上傳的問題,由于在rmi中無法傳輸文件流(比如rmi中的方法參數(shù)不能是FileInputStream之類的),那么我們只好選擇一種折中的辦法,就是先用FileInputStream將文件讀到一個 Byte數(shù)組中,然后把這個Byte數(shù)組作為參數(shù)傳進(jìn)RMI的方法中,然后在服務(wù)器端將Byte數(shù)組還原為outputStream,這樣就能通過RMI 來傳輸文件了
這樣做也有缺點,就是無法檢驗傳輸過來的數(shù)據(jù)的準(zhǔn)確性。
下面我就一個實例來講解一下
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();
}
}
//這個方法比較重要,通過這個方法把一個名為filename的文件轉(zhuǎn)化為一個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();
}
}
相關(guān)文章
Java報錯Java.text.ParseException的解決方法匯總
在Java開發(fā)的復(fù)雜世界中,錯誤處理是開發(fā)者必須面對的關(guān)鍵挑戰(zhàn)之一,其中,Java.text.ParseException就像一個隱藏在代碼叢林中的陷阱,常常讓開發(fā)者們陷入困惑,本文給大家介紹了Java報錯Java.text.ParseException的解決方法,需要的朋友可以參考下2024-10-10
Java結(jié)構(gòu)性設(shè)計模式中的裝飾器模式介紹使用
裝飾器模式又名包裝(Wrapper)模式。裝飾器模式以對客戶端透明的方式拓展對象的功能,是繼承關(guān)系的一種替代方案,本篇文章以虹貓藍(lán)兔生動形象的為你帶來詳細(xì)講解2022-09-09
spring boot下mybatis配置雙數(shù)據(jù)源的實例
這篇文章主要介紹了spring boot下mybatis配置雙數(shù)據(jù)源的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
淺析Spring?Cloud?Gateway中的令牌桶限流算法
這篇文章主要為大家淺析了Spring?Cloud?Gateway中的令牌桶限流算法原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
springboot獲取微信JSDK簽名信息的實現(xiàn)示例
本文介紹了如何在Spring Boot應(yīng)用中獲取微信JSDK的簽名信息,包括獲取接口URL、參數(shù)設(shè)置、簽名算法和獲取簽名結(jié)果的步驟,具有一定的參考價值,感興趣的可以了解一下2023-11-11
MyBatis-Flex+ShardingSphere-JDBC多數(shù)據(jù)源分庫分表實現(xiàn)
本文介紹了使用MyBatis-Flex和ShardingSphere-JDBC實現(xiàn)多數(shù)據(jù)源分庫分表的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10
使用SpringBoot集成Thymeleaf和Flying?Saucer實現(xiàn)PDF導(dǎo)出
在?Spring?Boot?項目中,生成?PDF?報表或發(fā)票是常見需求,本文將介紹如何使用?Spring?Boot?集成?Thymeleaf?模板引擎和?Flying?Saucer?實現(xiàn)?PDF?導(dǎo)出,并提供詳細(xì)的代碼實現(xiàn)和常見問題解決方案,需要的朋友可以參考下2024-11-11

