Сначало расскажу, что я хочу сделать, я студент и пишу курсовую по Java.
Есть клиент A и B, есть сервер S.
- Клиент A отправляет файл (открывает поток FileInputStream к файлу N и передаёт это потоку OutputStream сервера S).
- Клиент B знает об этом и получает поток вида FileInputStream файла от клиента A и пишет его при помощи FileOutputStream к себе на диск)
Возможна ли прямая передача через потоки, где сервер является только связывающим звеном двух потоков (принимающим и отдающим), которое не производит передачи, а вся передача происходит принимающей стороной (клиентов B)?
Если это невозможно, то получается единственный способ это сначало позволить клиенту A загрузить на сервер файл и затем оповестить клиента B о том, что он может его теперь скачать с сервера (не у явного клиента)
Последнее решение немного смущает, из-за того, что лично хочеться достигнуть стриминга между клиентами, а не залил-отдал, просто ещё немного не понимаю как к этому подойти.
PS: Передача файла будет проводиться через RMI Java. На данный момент я могу загружать файл и скачивать с сервера, я могу сделать следующее, Клиент А залил на сервер, клиент B скачал с сервера.
Часть решения я вижу в
ostermiller.org/convert_java_outputstream_inputstr... нужны объяснения как.
Реализовал, я последнюю передачу, так:
1. Клиент имеет менеджер
public class FileTransferManager {
private int BUFFER_SIZE = 1024 * 64;
private FileTransferRemote refService;
public FileTransferManager(String host, String serviceName) throws NotBoundException,
MalformedURLException, RemoteException {
refService =
(FileTransferRemote) Naming.lookup("rmi://" + host + "/" + serviceName);
}
public FileTransferRemote getRefService() {
return refService;
}
public void copy(InputStream in, OutputStream out) throws IOException {
byte[] b = new byte[BUFFER_SIZE];
int len;
while ((len = in.read(b)) >= 0) {
out.write(b, 0, len);
}
in.close();
out.close();
}
public void upload(File src, File dest) throws IOException {
copy(new FileInputStream(src), refService.getOutputStream(dest));
}
public void download(File src, File dest) throws IOException {
copy(refService.getInputStream(src), new FileOutputStream(dest));
}
}
2. Это интерфейс сервиса для передачи файлов (серверная)
// Интерфейс
public interface FileTransferRemote extends Remote {
public InputStream getInputStream(File f) throws IOException;
public OutputStream getOutputStream(File f) throws IOException;
public String method() throws RemoteException;
}
// Имплементация сервиса
public class FileTransfer extends AbstractService
implements FileTransferRemote {
public FileTransfer(int port, String name) throws RemoteException {
super(port, name);
}
@Override
public String method() throws RemoteException {
return this.getClass().getName();
}
@Override
public OutputStream getOutputStream(File f) throws IOException {
return new OutputStreamTransferable(
new FileOutputStreamHandler(new FileOutputStream(f)));
}
@Override
public InputStream getInputStream(File f) throws IOException {
// Каждый файл обёртывается в Remote Object File(In|Out)putStreamHandler, который описывает файл
// Дальше каждый File(In|Out)putStreamHandler заворачивается в Serializable File(In|Out)putStreamTransferable объект
// Дальше этот (In|Out)putStreamTransferable летит через сеть
return new InputStreamTransferable(
new FileInputStreamHandler(new FileInputStream(f)));
}
}