Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send a list of files over a socket in Java [duplicate]

Tags:

java

sockets

I have used the code here to send an individual file over a socket. However, I need to be able to send multiple files (basically all files in a directory) over the socket and have the client recognize how the separation between files. Frankly, I am at a complete loss for what to do. Any tips would be helpful.

NOTE 1: I need a way to send the files in one continuous stream that the client can segregate into individual files. It cannot rely on individual requests from the client.

NOTE 2: To answer a question I am pretty sure I will get in the comments, no, this is NOT homework.

EDIT it has been suggested that I could send the size of the file before the file itself. How can I do this, as sending a file over the socket is always done in either a predetermined array of bytes, or a single byte individually, rather than the long returned by File.length()

like image 443
ewok Avatar asked Jul 10 '12 19:07

ewok


2 Answers

Here is a full implementation:

Sender Side:

String directory = ...;
String hostDomain = ...;
int port = ...;

File[] files = new File(directory).listFiles();

Socket socket = new Socket(InetAddress.getByName(hostDomain), port);

BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);

dos.writeInt(files.length);

for(File file : files)
{
    long length = file.length();
    dos.writeLong(length);

    String name = file.getName();
    dos.writeUTF(name);

    FileInputStream fis = new FileInputStream(file);
    BufferedInputStream bis = new BufferedInputStream(fis);

    int theByte = 0;
    while((theByte = bis.read()) != -1) bos.write(theByte);

    bis.close();
}

dos.close();

Receiver Side:

String dirPath = ...;

ServerSocket serverSocket = ...;
Socket socket = serverSocket.accept();

BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
DataInputStream dis = new DataInputStream(bis);

int filesCount = dis.readInt();
File[] files = new File[filesCount];

for(int i = 0; i < filesCount; i++)
{
    long fileLength = dis.readLong();
    String fileName = dis.readUTF();

    files[i] = new File(dirPath + "/" + fileName);

    FileOutputStream fos = new FileOutputStream(files[i]);
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    for(int j = 0; j < fileLength; j++) bos.write(bis.read());

    bos.close();
}

dis.close();

I did not test it, but I hope it will work!

like image 110
Eng.Fouad Avatar answered Oct 23 '22 17:10

Eng.Fouad


You could send the size of the file first before each file, that way the client will know when the current file is over and expect the next (size). This will allow you to use one contiguous stream for all files.

like image 23
Attila Avatar answered Oct 23 '22 19:10

Attila