Приложение будет передавать множество файлов, и мне важно, что бы они были переданы с названиями. Для этого нужно отправлять каждый раз сообщение с названием файла или это как то можно сделать иначе?
Ответ
Первым байтом отправляете длину имени файла, следующие 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;
}
}
}
Комментариев нет:
Отправить комментарий