0

I have the following code that I am using to send a file to a client:

private void sendFile(Socket client) throws Exception {
        byte[] data = new byte[4096];
        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        FileInputStream fis = new FileInputStream("test.txt");

        while (fis.read(data, 0, data.length) != -1) {
            dos.write(data);
        }

        fis.close();
        dos.close();
}

The problem that I'm finding is that the file sizes are different after transfer. Upon further investigation, I discovered that the files were being duplicated on the last dos.write(data).

Example:

Original File:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras dictum diam neque, eu dictum sem efficitur ut.
Ut eu hendrerit risus.
In dapibus vel lectus at egestas.

Transferred File:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras dictum diam neque, eu dictum sem efficitur ut.
Ut eu hendrerit risus.
In dapibus vel lectus at egestas.
Ut eu hendrerit risus.
In dapib

I'm at wit's end here and I've already looked at hundreds of examples trying to fix this. I've tried dos.flush(), changing the read to dos.read(data), and changing the while loop condition. I'm expecting to transfer very large files so I don't want to load a file all at once.

EDIT:

I have been using both telnet and netcat from the command line for testing the download.

1
  • You need to check return values from both read and write. The value from read tells you how much was read and can safely be written. The value from write tells you how much was written and might prompt a retry. Commented Nov 30, 2016 at 6:27

1 Answer 1

1

see this method

https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#write(byte[],%20int,%20int)

and

https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#read(byte[],%20int,%20int)

len - the maximum number of bytes read.

and returns

the total number of bytes read into the buffer

You only want to write the amount of bytes that were read previously

so

  int br = -1;
  while ((br = fis.read(data, 0, data.length)) != -1) {
        dos.write(data, 0, br);
  }
Sign up to request clarification or add additional context in comments.

11 Comments

your link should be to InputStream read. The root cause is that the poster assumed that call to read guarantees reading as many bytes as are passed in the third argument. Of course, it doesn't.
I think that OP assumed that the array would be cleared
which is also a problem with the question - there isn't any 'duplicate data'. you're just writing stuff you didn't actually read, over and over. and the reason you're doing that is you never checked how much you actually read.
no. you should be keeping track of what you read and writing just that.
With my solution it is not necessary, but it is also another possible solution
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.