0

Does anybody knows how to download file from internet, using URL (http://.../File.mp4)? I am trying using NIO, but always the stream end at Integer.MAX_VALUE. My file is 2.5GB.

My code:

    String url = "http://.../Somefile.mp4";
    String filename = "Path/to/file/Something.mp4";

    boolean koncano = false;
    URLConnection conn = new URL(url).openConnection();
    conn.setRequestProperty("Range", "bytes=" + new File(filename).length() + "-");
    ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());
    long remain = conn.getContentLength();
    FileOutputStream fos = new FileOutputStream(filename, true);

    while (!koncano) {
        long downloaded = new File(filename).length();
        long buffer = (remain > 65536) ? 1 << 16 : remain;

        while (remain > 0) {
            long write = fos.getChannel().transferFrom(rbc, downloaded, buffer);
            downloaded += write;
            remain -= write;

            if (write == 0) {
                break;
            }
        }

        if (remain <= 0) {
            System.out.println("File is complete");
            rbc.close();
            fos.close();
            koncano = true;
        }
    }
EdenPac
  • 59
  • 4
  • 1
    Welcome to Stack Overflow! Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a [mcve]. Use the "edit" link to improve your *question* - do not add more information via comments. Thanks! – GhostCat Oct 10 '17 at 09:17
  • Dont link to an external site - provide example code here, within your quesiton! – GhostCat Oct 10 '17 at 09:18
  • I'd suspect you're using a `HttpURLConnection` or sth. similar which uses a `ByteArrayInputStream`. That in turn uses a `byte[]` and Java arrays have a maximum length of `Integer.MAX_VALUE`. – Thomas Oct 10 '17 at 09:22
  • use `fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);` see [this answer](https://stackoverflow.com/a/921400/4101906) – Rahmat Waisi Oct 10 '17 at 10:15

2 Answers2

1

Use the long version:

long remain = connection.getContentLengthLong();

Tip: if the file could be served compressed to a fraction, you could send a corresponding Accept header and optionally wrap the stream in a GZipInputStream.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
0

Try modify if (remain < 0) to if (remain <= 0)