您的位置:首页 > 编程语言 > PHP开发

OutputStream/InputStream

2017-09-20 20:42 85 查看

3,OutputStream/InputStream

在开发时,在获取HttpURLConnection对象之后,一般首先调用其connect方法,然后获取OutputStream,

这样就可以往OutputStream里面写值了。最后获取InputStream对象并进行相关操作。

conn.connect();
mOutput = conn.getOutputStream();
mOutput.write(postData);
mOutput.flush();
mOutput.close();
•••
int responseCode = conn.getResponseCode();
Log.d("www ","responseCode " + responseCode);
InputStream inputStream = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(isr);
String line = null;
while(((line = br.readLine()) != null)) {
Log.d("www ","line " + line);
}

获取OutputStream是调用HttpURLConnectionImpl的getOutputStream方法;

获取InputStream是调用HttpURLConnectionImpl的get InputStream方法;

3.1 OutputStream

HttpURLConnectionImpl的getOutputStream方法调用流程图如下,



HttpURLConnectionImpl的getOutputStream方法逻辑如下,

1,调用connect方法,

connect();

这也说明,只要调用了getOutputStream方法,就可以不用显示调用connect方法。

2,调用httpEngine的getBufferedRequestBody方法获取BufferedSink对象,

BufferedSink sink = httpEngine.getBufferedRequestBody();

3,调用获取的BufferedSink对象的outputStream方法,

return sink.outputStream();

HttpEngine的getBufferedRequestBody方法如下,

BufferedSink result = bufferedRequestBody;
if (result != null) return result;
Sink requestBody = getRequestBody();
return requestBody != null ? (bufferedRequestBody = Okio.buffer(requestBody)): null;

实际上返回的是通过Okio的buffer构造的RealBufferedSink对象。

public static BufferedSink buffer(Sink sink) {
if (sink == null) throw new IllegalArgumentException("sink == null");
return new RealBufferedSink(sink);
}

实际上, BufferedSink只是一个抽象类, RealBufferedSink才是具体的实现。

RealBufferedSink的outputStream方法返回的是匿名OutputStream对象,

@Override public OutputStream outputStream() {
return new OutputStream() {
@Override public void write(int b) throws IOException {
if (closed) throw new IOException("closed");
buffer.writeByte((byte) b);
emitCompleteSegments();
}
•••

实际上, OutputStream只是一个抽象类,一般**OutputStream都会继承该类并实现对应的方法。

3.2 InputStream

HttpURLConnectionImpl的getInputStream方法调用流程图如下,



getInputStream方法主要逻辑如下,

1,调用getResponse获取HttpEngine对象,

HttpEngine response = getResponse();

2,获取InputStream对象,

return response.getResponse().body().byteStream();

HttpEngine的getResponse方法返回的是Response对象,

Response对象的body方法返回的是ResponseBody对象,

ResponseBody的byteStream方法如下,

public final InputStream byteStream() throws IOException {
return source().inputStream();
}

ResponseBody只是一个抽象方法,具体的source方法在子类RealResponseBody中实现,

public BufferedSource source() {
return source;
}

返回的是RealBufferedSource对象,其inputStream方法如下,

return new InputStream() {
@Override public int read() throws IOException {
if (closed) throw new IOException("closed");
if (buffer.size == 0) {
long count = source.read(buffer, Segment.SIZE);
if (count == -1) return -1;
}
return buffer.readByte() & 0xff;
}
•••

和OutputStream的逻辑完全相同, InputStream也只是一个抽象类,在此也是一个匿名实现。

因此,通过HttpURLConnectionImpl对象获取的OutputStream/InputStream对象分别是RealBufferedSink/RealBufferedSourc

e的内部匿名类OutputStream/InputStream。

并且OutputStream/InputStream都是利用Buffer来实现的。

RealBufferedSink的内部匿名类OutputStream的write方法如下,

public void write(int b) throws IOException {
if (closed) throw new IOException("closed");
buffer.writeByte((byte) b);
emitCompleteSegments();
}

Buffer变量是RealBufferedSink的构造方法中初始化的,是Buffer对象,

public RealBufferedSink(Sink sink) {
this(sink, new Buffer());
}

RealBufferedSource的内部匿名类InputStream的read方法如下,

public int read() throws IOException {
if (closed) throw new IOException("closed");
if (buffer.size == 0) {
long count = source.read(buffer, Segment.SIZE);
if (count == -1) return -1;
}
return buffer.readByte() & 0xff;
}

因此, OutputStream的wite方法最后调用的是Buffer的writeByte方法;

InputStream的read方法最后调用的是Buffer的readByte方法;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息