Java NIO从inputstream读取大文件

时间:2015-10-02 21:16:03

标签: java nio

我想读取一个大的InputStream并将其作为文件返回。所以我需要拆分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();

但它不会影响性能。

2 个答案:

答案 0 :(得分:2)

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

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

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

你需要在单独的线程中读取来自URLConnections的输入流,因为这会阻塞IO(不确定NIO包装是否有帮助)。

答案 1 :(得分:-1)

您可以使用每个频道的位置(长)方法开始阅读。

检查一下。

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

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

  

并行下载

     

要并行下载文件的多个部分,我们需要创建   多线程。每个线程的实现与简单类似   上面的线程,除了它只需要下载的一部分   下载文件。为此,HttpURLConnection或其超类   URLConnection为我们提供了方法setRequestProperty来设置范围   我们想要下载的字节数。

// 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/