سؤال

I'm trying to send files to my server. I got it working with files smaller than 100mb. Otherwise I ran out of heap. So I remade it but can't really get it to work. I also got the to work except for reading the last data I get stuck in bis.read(buffer) because it didn't know when the file ended. So I tried to send the length of each segment so that the bufferedInputStream know when to stop reading.

Any idea what's wrong?

Sender Code:

        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[2048];
        Integer bytesRead = 0;
        BufferedOutputStream bos = new BufferedOutputStream(clientSocket.getOutputStream());
        BufferedInputStream bis = new BufferedInputStream(fis);

        while ((bytesRead = bis.read(buffer)) > 0) {
            objectOutStream.writeObject(bytesRead);
            bos.write(buffer, 0, bytesRead);

        }
        System.out.println("Sucess sending file");

Receiver (Server):

       fileName = request.getFileName();
       int size = (int) request.getSize();

        BufferedInputStream bis = new BufferedInputStream(clientSocket.getInputStream());

        FileOutputStream fos = new FileOutputStream(fileName);
        int totalBytesReceived = 0;
        int blockSize = 0;
        while (totalBytesReceived < size) {
            Object o = ois.readObject();

            if (!(o instanceof Integer)) {
                System.out.println("Something is wrong");
            }
            blockSize = (Integer) o;

            buffer = new byte[blockSize];

            bis.read(buffer);
            totalBytesReceived += blockSize;
            fos.write(buffer, 0, blockSize);
        }
        System.out.println("File succes");
هل كانت مفيدة؟

المحلول

Your reading code on the server side should look the same as on the client side.

// copy from bis to bos, using a buffer.
for(int len; (len = bis.read(buffer)) > 0) {
    bos.write(buffer, 0, len);
}

On the client side you want

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename));
BufferedOutputStream bos = new BufferedOutputStream(clientSocket.getOutputStream());

on the server side you want.

BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filename));

when finished you want to

bos.close();
bis.close();

If you are going to use an ObjectOutputStream (and I suggest you don't) you need to use only this stream, not a mixture of streams.

نصائح أخرى

You can simplify your code. You will get -1 from bis.read() when you reach the end of the stream. That way you don't need to know how long the file will be. And flush() and close() the streams on the server and client. As the other poster says, don't use ObjectOutputStream or ObjectIntputStream. You'll get serialization headers which will appear to corrupt your data.

   fileName = request.getFileName();

    BufferedInputStream bis = new BufferedInputStream(clientSocket.getInputStream());

    FileOutputStream fos = new FileOutputStream(fileName);
    int data = bis.read(); //reads an int
    while (data != -1) {
        fos.write(data);
        data = bis.read();

    }
    fos.flush();
    fos.close();

    System.out.println("File succes");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top