Зачем использовать RMI
В этом проекте я продумывал множество способов связи между клиентом и сервером. Поскольку я работал над многофункциональным клиентским приложением, я в итоге выбрал технологию между RMI и Java-сокетами. Среди них RMI не отличается высокой гибкостью. И клиент, и сервер должны быть написаны на Java, но использовать его удобнее. С другой стороны, java-сокеты хоть и более гибкие, но требуют определения протокола связи между сервером и клиентом. Это довольно хлопотно. Несколько раз взвесив, я наконец выбрал RMI для связи сервер-клиент.
Проблема с загрузкой файла
В процессе использования java-rmi вы неизбежно столкнетесь с проблемой загрузки файлов. Поскольку файловые потоки не могут передаваться в rmi (например, параметрами метода в rmi не могут быть FileInputStream и тому подобное), то приходится выбирать компромисс. Лучший способ — сначала использовать FileInputStream для чтения файла в массив Byte, затем передать этот массив Byte в качестве параметра в метод RMI, а затем восстановить массив Byte в выходной поток на стороне сервера, чтобы его можно было использовать. прошел через РМИ Давайте перенесем файлы
Это также имеет тот недостаток, что точность передаваемых данных не может быть проверена.
Позвольте мне объяснить это на примере ниже.
ФайлКлиент
Скопируйте код кода следующим образом:
пакет rmiupload;
импортировать java.io.BufferedInputStream;
импортировать java.io.File;
импортировать java.io.FileInputStream;
импортировать java.io.FileNotFoundException;
импортировать java.io.IOException;
импортировать java.net.MalformedURLException;
импортировать java.rmi.Именование;
импортировать java.rmi.NotBoundException;
импортировать java.rmi.RemoteException;
общественный класс FileClient {
общественный FileClient() {
// TODO Автоматически сгенерированная заглушка конструктора
}
public static void main(String[] args) {
пытаться {
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 Автоматически сгенерированный блок catch
е.printStackTrace();
}
}
//Этот метод более важен. С помощью этого метода файл с именем filename преобразуется в массив байтов.
частный байт [] fileToByte (строковое имя файла) {
байт [] б = ноль;
пытаться {
Файл файл = новый файл (имя файла);
b = новый байт[(int) file.length()];
BufferedInputStream = новый BufferedInputStream (новый FileInputStream (файл));
is.read(б);
} catch (FileNotFoundException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
} catch (IOException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
}
вернуть б;
}
}
Филдатасервице
пакет rmiupload;
импортировать java.net.URL;
импортировать java.rmi.Remote;
импортировать java.rmi.RemoteException;
общедоступный интерфейс FileDataService расширяет Remote {
//Имя файла здесь должно быть адресом, по которому файл хранится на стороне сервера
public void upload (имя файла String, файл byte[]) выдает RemoteException;
}
FileDataService_imp
Скопируйте код кода следующим образом:
пакет rmiupload;
импортировать java.io.BufferedOutputStream;
импортировать java.io.File;
импортировать java.io.FileNotFoundException;
импортировать java.io.FileOutputStream;
импортировать java.io.IOException;
импортировать java.net.URL;
импортировать java.rmi.RemoteException;
импортировать java.rmi.server.RMIClientSocketFactory;
импортировать java.rmi.server.RMIServerSocketFactory;
импортировать java.rmi.server.UnicastRemoteObject;
публичный класс FileDataService_imp расширяет UnicastRemoteObject и реализует FileDataService{
public FileDataService_imp() выдает RemoteException {
}
@Override
public void upload (имя файла String, byte[] fileContent) выдает RemoteException {
Файл файл = новый файл (имя файла);
пытаться {
если (!file.exists())
файл.createNewFile();
BufferedOutputStream os = новый BufferedOutputStream (новый FileOutputStream (файл));
os.write(fileContent);
} catch (FileNotFoundException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
} catch (IOException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
}
; }
}
файловый сервер
Скопируйте код кода следующим образом:
пакет rmiupload;
импортировать java.net.MalformedURLException;
импортировать java.rmi.Именование;
импортировать java.rmi.RemoteException;
импортировать java.rmi.registry.LocateRegistry;
общественный класс FileServer {
FileDataService fileDataService;
общественный FileServer() {
пытаться {
fileDataService = новый FileDataService_imp ();
LocateRegistry.createRegistry(9001);
Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
} catch (RemoteException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
} catch (MalformedURLException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
}
}
/**
* @param аргументы
*/
public static void main(String[] args) {
новый Файловый Сервер();
}
}