Pourquoi utiliser RMI
Dans ce projet, j'ai pensé à de nombreuses façons de communiquer entre le client et le serveur. Comme je travaillais sur une application client riche, j'ai finalement sélectionné la technologie entre RMI et Java-sockets. Parmi eux, RMI La flexibilité n'est pas élevée. Le client et le serveur doivent être écrits en Java, mais c'est plus pratique à utiliser. D'un autre côté, les sockets Java, bien que plus flexibles, doivent définir le protocole de communication entre le serveur et le client. C'est assez gênant. Après avoir réfléchi plusieurs fois, j'ai finalement choisi RMI pour la communication serveur-client.
Problème de téléchargement de fichier
Lors de l'utilisation de java-rmi, vous rencontrerez inévitablement un problème de téléchargement de fichiers. Étant donné que les flux de fichiers ne peuvent pas être transmis dans rmi (par exemple, les paramètres de méthode dans rmi ne peuvent pas être FileInputStream, etc.), nous devons alors choisir un compromis. . La meilleure façon est d'utiliser d'abord FileInputStream pour lire le fichier dans un tableau d'octets, puis de transmettre ce tableau d'octets en tant que paramètre dans la méthode RMI, puis de restaurer le tableau d'octets dans un flux de sortie côté serveur, afin qu'il puisse être. passé par le RMI Transférons des fichiers
Cela présente également l'inconvénient que l'exactitude des données transmises ne peut pas être vérifiée.
Permettez-moi de l'expliquer avec un exemple ci-dessous.
FichierClient
Copiez le code comme suit :
paquet rmiupload ;
importer java.io.BufferedInputStream ;
importer java.io.File ;
importer java.io.FileInputStream ;
importer java.io.FileNotFoundException ;
importer java.io.IOException ;
importer java.net.MalformedURLException ;
importer java.rmi.Naming ;
importer java.rmi.NotBoundException ;
importer java.rmi.RemoteException ;
classe publique FileClient {
public FileClient() {
// TODO Stub de constructeur généré automatiquement
}
public static void main (String[] arguments) {
essayer {
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 Bloc catch généré automatiquement
e.printStackTrace();
}
}
//Cette méthode est plus importante. Grâce à cette méthode, un fichier nommé filename est converti en un tableau d'octets.
octet privé[] fileToByte(String nom de fichier){
octet[] b = nul ;
essayer {
Fichier fichier = nouveau fichier (nom de fichier);
b = nouvel octet[(int) file.length()];
BufferedInputStream est = new BufferedInputStream(new FileInputStream(file));
est.read(b);
} catch (FileNotFoundException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
retourner b ;
}
}
Service de données de fichiers
paquet rmiupload ;
importer java.net.URL ;
importer java.rmi.Remote ;
importer java.rmi.RemoteException ;
l'interface publique FileDataService étend Remote{
//Le nom du fichier ici doit être l'adresse où le fichier est stocké côté serveur
le téléchargement public void (nom de fichier String, fichier byte []) lève RemoteException ;
}
FileDataService_imp
Copiez le code comme suit :
paquet rmiupload ;
importer java.io.BufferedOutputStream ;
importer java.io.File ;
importer java.io.FileNotFoundException ;
importer java.io.FileOutputStream ;
importer java.io.IOException ;
importer java.net.URL ;
importer java.rmi.RemoteException ;
importer java.rmi.server.RMIClientSocketFactory ;
importer java.rmi.server.RMIServerSocketFactory ;
importer java.rmi.server.UnicastRemoteObject ;
la classe publique FileDataService_imp étend UnicastRemoteObject implémente FileDataService{
public FileDataService_imp() lance RemoteException {
}
@Outrepasser
public void upload (String filename, byte[] fileContent) lance RemoteException {
Fichier fichier = nouveau fichier (nom de fichier);
essayer {
si (!file.exists())
fichier.createNewFile();
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
os.write(fileContent);
} catch (FileNotFoundException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
; }
}
Serveur de fichiers
Copiez le code comme suit :
paquet rmiupload ;
importer java.net.MalformedURLException ;
importer java.rmi.Naming ;
importer java.rmi.RemoteException ;
importer java.rmi.registry.LocateRegistry ;
serveur de fichiers de classe publique {
FileDataService fileDataService;
serveur de fichiers public() {
essayer {
fileDataService = nouveau FileDataService_imp();
LocateRegistry.createRegistry(9001);
Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
} catch (RemoteException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
}
/**
* @param arguments
*/
public static void main (String[] arguments) {
nouveau serveur de fichiers ();
}
}