@alvstad

Как отправить имя файла, а потом и сам файл в ByteBuffer Java NIO?

Доброго времени суток. По урокам смог разобраться в том, как отправить файл с клиента на сервер используя Bytebuffer Java NIO. Теперь встрял такой вопрос, что сначала мне нужно отправить оригинальное название файла (его я беру FileChooser'ом из UI). То есть, FileChooser'ом я тыкаю на файле и сначала у меня должно отправить имя файла, затем должен создаться на сервере файл с таким именем, а потом уже должен отправить сам файл. Суть в том, что мне нужно отправить файл сохраняя оригинальное название.
Код клиентхендлера
public class FileTransferClient {

    private static final String HOST = "localhost";
    private static final int PORT = 9999;

    public void sendFile(String path) throws IOException {
        File file = new File(path);
        System.out.println("file length = " + file.length());
        FileChannel fileChannel = new FileInputStream(file).getChannel();
        SocketAddress socketAddress = new InetSocketAddress(HOST, PORT);
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(socketAddress);

        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putLong(file.length());
        buffer.flip();
        socketChannel.write(buffer);

        long total = 0;
        while (total < file.length()) {
            long transferred = fileChannel.transferTo(total, file.length() - total, socketChannel);
            total += transferred;
        }

        buffer.clear();
        socketChannel.read(buffer);
        buffer.flip();
        long length = buffer.getLong();
        System.out.println("bytes received by server = " + length);

        socketChannel.finishConnect();
    }
}


Код с сервера
public class Server {

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(9999));
        SocketChannel socketChannel = serverSocketChannel.accept();

        final File outputFile = new File("rufus.exe");

        ByteBuffer buffer = ByteBuffer.allocate(8);
        socketChannel.read(buffer);
        buffer.flip();
        long length = buffer.getLong();
        FileChannel fileChannel = new FileOutputStream(outputFile).getChannel();
        long total = 0;
        while (total < length) {
            long transferred = fileChannel.transferFrom(socketChannel, total, length - total);
            if (transferred <= 0){
                break;
            }
            total += transferred;
        }
        buffer.clear();
        buffer.putLong(total);
        buffer.flip();
        socketChannel.write(buffer);
        serverSocketChannel.close();
        System.out.println("length received = " + length + ", saved file length = " + outputFile.length());
    }
}
  • Вопрос задан
  • 205 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Dmtm
Android
и в чем проблема?
очевидно что надо договориться о протоколе, позволяющем разделелять поток бинарных данных, например, если в потоке встеретилось !"№";№%"№%:№;: то это начало передачи нового файла, потом, опять же например, можно следующие 2 байта отвести под размер имени файла, а еще следующие 4 - под размер самого файла, сервер получает начало передачи, узнает сколько байт занимает имя, сколько сам файл, в одном общем бинарном потоке
Ответ написан
mayton2019
@mayton2019 Куратор тега Java
Bigdata Engineer
Имя файла с клиента обычно несёт мало смысла. Ну будет там 100500 файлов с именем Книга(1).xls. А тебе нужна какая-то уникальность.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы