Страницы

Поиск по вопросам

среда, 10 октября 2018 г.

Как передать название файла по сокету?

Приложение будет передавать множество файлов, и мне важно, что бы они были переданы с названиями. Для этого нужно отправлять каждый раз сообщение с названием файла или это как то можно сделать иначе?


Ответ

Первым байтом отправляете длину имени файла, следующие 4 байта - длина файла, следом байты имени файла, а потом байты самого файла. Или, чтобы не заморачиваться с конвертацией данных, можно поля чуточку расширить:
Server.java
package com.example;
import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.net.ServerSocket; import java.net.Socket;
public class Server { private static int PORT = 2121; private static String FOLDER = "./files";
public static void main(String[] args) { File sourceDir = new File(FOLDER);
try (ServerSocket listener = new ServerSocket(PORT)) { while (true) { try (Socket socket = listener.accept(); OutputStream out = socket.getOutputStream()) { for (String fileName : sourceDir.list()) { // Преобразовываем строку, содержащую имя файла, // в массив байт byte[] name = fileName.getBytes("utf-8"); // Отправляем длину этого массива out.write(name.length); // Отправляем байты имени out.write(name);
File file = new File(FOLDER + "/" + fileName);
// Получаем размер файла long fileSize = file.length(); // Конвертируем его в массив байт ByteBuffer buf = ByteBuffer.allocate(Long.BYTES); buf.putLong(fileSize); // И отправляем out.write(buf.array());
try (FileInputStream in = new FileInputStream(file)) { // Читаем файл блоками по килобайту byte[] data = new byte[1024]; int read; while ((read = in.read(data)) != -1) { // И отправляем в сокет out.write(data); } } catch(IOException exc) { exc.printStackTrace(); } } } catch(IOException exc) { exc.printStackTrace(); } } } catch(IOException exc) { exc.printStackTrace(); } } }
Client.java
package com.example;
import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.net.Socket;
public class Client { private static int PORT = 2121; private static String HOST = "localhost"; private static String FOLDER = "./files";
public static void main(String[] args) { try (Socket s = new Socket(HOST, PORT); InputStream in = s.getInputStream()) {
// Читаем размер имени int nameSize; while((nameSize = in.read()) != -1) { // Читаем само имя byte[] name = new byte[nameSize + 1]; in.read(name, 0, nameSize); // Преобразовываем обратно в строку String fileName = new String(name, "utf-8").trim(); System.out.println(fileName);
File file = new File(FOLDER + "/" + fileName); try (FileOutputStream out = new FileOutputStream(file)) { // Читаем размер файл byte[] fileSizeBuf = new byte[8]; in.read(fileSizeBuf, 0, 8); // Преобразовываем в long ByteBuffer buf = ByteBuffer.allocate(Long.BYTES); buf.put(fileSizeBuf); buf.flip(); long fileSize = buf.getLong();
// Читаем содержимое файла блоками по килобайту int read = 0; byte[] data = new byte[1024]; while (read < fileSize) { read += in.read(data); // И пишем в файл out.write(data); } } catch(IOException exc) { exc.printStackTrace(); } } } catch(IOException exc) { exc.printStackTrace(); return; } } }

Комментариев нет:

Отправить комментарий