inputstream 获取文件_从HTTP到文件的极致优化(零拷贝实现)

从HTTP到文件

  • FileChannel 和非直接模式 Buffer vs. FileChannel 和直接模式 Buffer

  • FileChannel.transferTo() vs. FileChannel.transferFrom() vs. FileChannel.map()

  • 三种 Files.copy() 方法

  • FileChannel 和非直接模式 Buffer vs. FileChannel.transferTo() vs. Path 到 Path

背景:如何高效的从HTTP请求响应数据,写入到文件中。

http请求返回内容response.getEntity().getContent()

可以获取本次调用的InputStream,InputStream实际上是本次请求打开的socket返回的InputStream,可以读取socket的数据。

详细内容可以参考socket.getInputStream()方法的注释,来获取官方说明。

我们的目的是把从InputStream中读取的数据,写入到文件中。

1 常规方法

普通的解析是利用``org.apache.http.util.EntityUtil.toString( final HttpEntity entity, final Charset defaultCharset)`方法,读取Stream中的内容,放入到一个CharArrayBuffer对象中,然后转换成String对象。

大致过程如下:

e3b00680c2c078f759334c2ce38a2262.png
image-20200826205852345
  1. DMA传输
  2. CPU传输,上下文切换
  3. CPU传输,上下文切换
  4. DMA传输

DMA(Direct Memory Access 直接存储器读取),**即直接存储器存取,是一种快速传送数据的机制。**DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。

第一步的DMA传输到Socket缓冲区,因为一切传输的底层都是socket,一个http请求必定是在服务的和客户端建立起socket连接,来发送请求。从网卡传输的数据被本地对应的socket接收,然后赋值给通过建立起相应的响应Response实例中的InputStream对象(打开一个可以传输socket中buffer数据的通道),参考代码:

org.apache.http.impl.io.SocketInputBuffer的构造方法中:

 public SocketInputBuffer(final Socket socket,int buffersize,final HttpParams params) throws IOException {
    
        super();
        if (socket == null) {
            throw new IllegalArgumentException("Socket may not be null");
        }
        this.socket = socket;
        this.eof = false;
        if (buffersize 0) {
            buffersize = socket.getReceiveBufferSize();
        }
        if (buffersize 1024) {
            buffersize = 1024;
        }
        init(socket.getInputStream(), buffersize, params);
    }

此方法被org.apache.http.impl.SocketHttpServerConnection调用,这个方法会初始化建立连接的流入流出通道:

   protected void bind(final Socket socket, final HttpParams params) throws    IOException {
    
        if (socket == null) {
            throw new IllegalArgumentException("Socket may not be null");
        }
        if (params == null) {
            throw new IllegalArgumentException("HTTP parameters may not be null");
        }
        this.socket = socket;

        int
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值