繁体   English   中英

Java NIO 从输入流读取大文件

[英]Java NIO read large file from inputstream

我想读取一个大的 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();

但是不影响性能。

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

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

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

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

您可以对每个通道使用 position(long) 方法来开始读取。

检查这个。

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/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM