Java NIO 从输入流读取大文件

标签 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();

但不影响性能。

最佳答案

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

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

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

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

关于Java NIO 从输入流读取大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32915982/

相关文章:

java - Mockito 定义 'when' 调用答案

java - 存储在 getPoint() 对象中的坐标

java - oracle java教程中可能有错误?

tomcat - Tomcat Http11NioProtocol的缺点

java - 在Java中如何从另一个类(不是继承)调用一个类?

java - Google App Engine Query Execute 只接受 3 个参数

java - 使用CXF集成jaxb绑定(bind)文件生成基于WSDL的客户端

java - 当 io 包已经有方法可用时,java nio 包的确切用途是什么

java - Files.isDirectory NullPointerException

java - Channel中如何高效转换字符编码?