The application will transfer multiple files, and it is important to me that they be transferred with names. To do this, you need to send each time a message with the name of the file or is it something else can be done?

    2 answers 2

    The first byte send the length of the file name, the next 4 bytes - the length of the file, followed by the bytes of the file name, and then the bytes of the file itself. Or, in order not to bother with converting data, you can expand the fields a bit:

    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; } } } 
    • Good afternoon, tell me what can replace this line.for (String fileName: sourceDir.list ()). When you start the client and server on the server side, Exception in thread "main" java.lang.NullPointerException appears at java.base / java.util.Objects.requireNonNull (Objects.java:221) at Server.main (Server.java:2 the lines are highlighted in yellow, and the idea proposes to replace it with Objects.requireNonNull (sourceDir.list ()) But the result is the same, tell me what can be replaced - Akalit
    • It is necessary not to replace, but to figure out what this line does and why it gives an error. - Sergey Gornostaev
    • As I understand in this line, we create a forech loop after we create a backup string variable to which the lines from the file arrive, while trying to split the file into an array of strings - Akalit
    • An error may occur in this line if there is a problem with the file. Thanks, I will try to search =) - Akalit

    There are several approaches to solving your problem:

    1. Serialization. Use the built-in serialization ( Java Serialization API ), or one of the popular libraries . That is, you serialize the object, transfer and deserialize it on the receiving side.

    2. Use your data exchange protocol. For example, after a connection is established, the client sends the file name, receives a confirmation from the server, then sends the contents of the file, and again receives confirmation of the receipt of the file.

    3. Send the file name and its contents in one request, then you need to organize the format of the data transfer, as already described in this response