Java multiple file transfer over socket

I did it like this, it is working perfectly, you can take a look:

Send

byte[] done = new byte[3];
String str = "done";  //randomly anything
done = str.getBytes();
for (int i = 0; i < files.size(); i++) {
    System.out.println(files.get(i).getName());
    FileInputStream fis = new FileInputStream(files.get(i));
    while ((n = fis.read(buf)) != -1) {
        dos.write(buf, 0, n);
        System.out.println(n);
        dos.flush();
    }
    //should i close the dataoutputstream here and make a new one each time?                 
    dos.write(done, 0, 3);
    dos.flush();
}
//or is this good?
dos.close();

Receive

for (int i = 0; i < files.size(); i++) {
    System.out.println("Receiving file: " + files.get(i).getName());
    //create a new fileoutputstream for each new file
    fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" + files.get(i).getName());
    //read file
    while ((n = dis.read(buf)) != -1 && n != 3) {
        fos.write(buf, 0, n);
        fos.flush();
    }
    fos.close();
}

You are reading the socket until read() returns -1. This is the end-of-stream condition (EOS). EOS happens when the peer closes the connection. Not when it finishes writing one file.

You need to send the file size ahead of each file. You're already doing a similar thing with the file count. Then make sure you read exactly that many bytes for that file:

String filename = dis.readUTF();
long fileSize = dis.readLong();
FileOutputStream fos = new FileOutputStream(filename);
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1)
{
  fos.write(buf,0,n);
  fileSize -= n;
}
fos.close();

You can enclose all this in a loop that terminates when readUTF() throws EOFException. Conversely of course you have to call writeUTF(filename) and writeLong(filesize) at the sender, before sending the data.

Tags:

Java