从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对象。
大致过程如下:
- DMA传输
- CPU传输,上下文切换
- CPU传输,上下文切换
- 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