Java NIO 从输入流读取大文件

Java NIO read large file from inputstream

我想读取一个大的 InputStream 并 return 它作为一个文件。所以我需要拆分 InputStream(或者我应该在多个线程中读取 InputStream)。我怎样才能做到这一点?我正在尝试做这样的事情:

    URL url = new URL("path");
    URLConnection connection = url.openConnection();
    int fileSize = connection.getContentLength();

    InputStream is = connection.getInputStream();
    ReadableByteChannel rbc1 = Channels.newChannel(is);
    ReadableByteChannel rbc2 = Channels.newChannel(is);

    FileOutputStream fos = new FileOutputStream("file.ext");

    FileChannel fileChannel1 = fos.getChannel();
    FileChannel fileChannel2 = fos.getChannel();
    fileChannel1.transferFrom(rbc1, 0, fileSize/2);
    fileChannel2.transferFrom(rbc2, fileSize/2, fileSize/2);

    fos.close();

但不影响性能。

您可以使用position(long) 方法为每个频道开始阅读。

检查这个。

http://tutorials.jenkov.com/java-nio/file-channel.html#filechannel-position

此外,如果您想部分下载文件,

Parallel Downloading

To download multiple parts of a file parallelly, we need to create multiple threads. Each thread is implemented similarly to the simple thread above, except that it needs to download only a part of the downloaded file. To do that, the HttpURLConnection or its super class URLConnection provides us method setRequestProperty to set the range of the bytes we want to download.

// open Http connection to URL
HttpURLConnection conn = (HttpURLConnection)mURL.openConnection();

// set the range of byte to download
String byteRange = mStartByte + "-" + mEndByte;
conn.setRequestProperty("Range", "bytes=" + byteRange);

// connect to server
conn.connect();

这会对您有所帮助。

我在这里找到了这个答案,你可以查看完整教程。

http://luugiathuy.com/2011/03/download-manager-java/

您可以打开到同一资源的多个 (HTTP) 连接 (URL),但使用 HTTP Range: Header 使每个流从另一个点开始读取。这实际上可以加快数据传输速度,尤其是当高延迟成为问题时。您不应该过度并行化,请注意它会给服务器带来额外的负载。

connection1.setRequestProperty("Range", "bytes=0-" + half);
connection2.setRequestProperty("Range", "bytes=" + half+1 +"-");

这也可用于恢复下载。需要服务器支持。它可以用 Accept-Ranges: bytes 来宣布这一点,但不必这样做。准备好第一个连接可能 return 整个请求的实体(状态 200 与 206)。

您需要在单独的线程中从 URL 连接读取输入流,因为这是阻塞 IO(不确定 NIO 包装在这里是否有帮助)。