Can't send large files over socket in Java

前端 未结 5 1638
执念已碎
执念已碎 2021-01-14 06:51

I got working server and client applications, they work perfect while sending small files, but when I try to send for example movie file that is 700mb over socket it gives m

相关标签:
5条回答
  • 2021-01-14 06:57

    The problem is that you are trying to load the entire file at once into memory (via readFully), which exceeds your heap space (which by default is 256mb I think).

    You have two options:

    1. Good option: load the file in chunks (e.g. 1024 bytes at a time) and send it like that. Takes a bit more effort to implement.
    2. Bad option: increase your heap space via -Xmx option. Not recommended, I mostly mentioned this just in case you will need a bit more heap space for a program, but in this case it's a really bad idea.

    For option one you can try something like:

    DataInputStream in = new DataInputStream(new FileInputStream("file.txt"));
    byte[] arr = new byte[1024];
    try {
        int len = 0;
        while((len = in.read(arr)) != -1)
        {
            // send the first len bytes of arr over socket.
        } 
    } catch(IOException ex) {
        ex.printStackTrace();
    }
    
    0 讨论(0)
  • 2021-01-14 07:04

    Just like you're using a buffer on the server side the send the data, use a buffer in your applet/client to read it. If you're transferring a large file, you will clearly run out of memory when you use readFully(). This method is only useful for cases where you know your data will be really, really small.

    0 讨论(0)
  • 2021-01-14 07:08

    OutOfMemoryError is thrown when your program reaches the heap size limit. You loads entire file to your RAM. The default heap size is 1/4 of physical memory size or 1GB, so your program reaches the limit (you probably have got 2GB RAM, so the heap size is 512MB).

    You should read your file in chunks (e.g. 10MB), so you won't reach the heap size limit, and you can resend chunks in the case of some error, instead of resending whole file. You can even read chunks in different thread, so when you're sending 1 chunk, you can load the second chunk, and when you'll sent the first one, you can start sending the second immediately.

    0 讨论(0)
  • 2021-01-14 07:11

    The problem is that in your client you create a byte array for the entire file.

    byte[] fileLength = new byte[(int) file.length()];  //potentially huge buffer allocated here
    

    You should do the same thing you do on the server side and read the file chunk by chunk into a fixed size buffer.

    0 讨论(0)
  • 2021-01-14 07:15

    It gives you OutOfMemoryError because you are trying to read the entire file into memory before sending it. This is 100% completely and utterly unnecessary. Just read and write chunks, much as you are doing in the receiving code.

    0 讨论(0)
提交回复
热议问题