org.apache.thrift.transport.TTransport
传输组件抽象描述。
public abstract class TTransport implements Closeable {
public abstract boolean isOpen();
public boolean peek() { return isOpen(); }
public abstract void open() throws TTransportException;
public abstract void close();
public abstract int read(byte[] buf, int off, int len) throws TTransportException;
public int readAll(byte[] buf, int off, int len)
throws TTransportException {
int got = 0;
int ret = 0;
while (got < len) {
ret = read(buf, off+got, len-got);
if (ret <= 0) {
throw new TTransportException(
"Cannot read. Remote side has closed. Tried to read "
+ len
+ " bytes, but only got "
+ got
+ " bytes. (This is often indicative of an internal error on the server side. Please check your server logs.)");
}
got += ret;
}
return got;
}
public void write(byte[] buf) throws TTransportException {
write(buf, 0, buf.length);
}
public abstract void write(byte[] buf, int off, int len) throws TTransportException;
public void flush() throws TTransportException {}
public byte[] getBuffer() { return null; }
public int getBufferPosition() { return 0; }
public int getBytesRemainingInBuffer() { return -1; }
public void consumeBuffer(int len) {}
}
TIOStreamTransport
基于 IO 流的传输组件。
public class TIOStreamTransport extends TTransport {
protected InputStream inputStream_ = null;
protected OutputStream outputStream_ = null;
public int read(byte[] buf, int off, int len) throws TTransportException {
if (inputStream_ == null) {
throw new TTransportException(TTransportException.NOT_OPEN, "Cannot read from null inputStream");
}
int bytesRead;
try {
bytesRead = inputStream_.read(buf, off, len);
} catch (IOException iox) {
throw new TTransportException(TTransportException.UNKNOWN, iox);
}
if (bytesRead < 0) {
throw new TTransportException(TTransportException.END_OF_FILE);
}
return bytesRead;
}
public void write(byte[] buf, int off, int len) throws TTransportException {
if (outputStream_ == null) {
throw new TTransportException(TTransportException.NOT_OPEN, "Cannot write to null outputStream");
}
try {
outputStream_.write(buf, off, len);
} catch (IOException iox) {
throw new TTransportException(TTransportException.UNKNOWN, iox);
}
}
TMemoryInputTransport
封装了一个字节数组byte[]来做输入流的封装
public final class TMemoryInputTransport extends TTransport {
// 共有 endPos_ - pos_ 个元素
private byte[] buf_;
// 开始读位置
private int pos_;
private int endPos_;
public TMemoryInputTransport() {
}
public TMemoryInputTransport(byte[] buf) {
reset(buf);
}
public TMemoryInputTransport(byte[] buf, int offset, int length) {
reset(buf, offset, length);
}
public void reset(byte[] buf) {
reset(buf, 0, buf.length);
}
public void reset(byte[] buf, int offset, int length) {
buf_ = buf;
pos_ = offset;
endPos_ = offset + length;
}
public void clear() {
buf_ = null;
}
@Override
public void close() {}
@Override
public boolean isOpen() {
return true;
}
@Override
public void open() throws TTransportException {}
@Override
public int read(byte[] buf, int off, int len) throws TTransportException {
int bytesRemaining = getBytesRemainingInBuffer();
int amtToRead = (len > bytesRemaining ? bytesRemaining : len);
if (amtToRead > 0) {
System.arraycopy(buf_, pos_, buf, off, amtToRead);
consumeBuffer(amtToRead);
}
return amtToRead;
}
@Override
public void write(byte[] buf, int off, int len) throws TTransportException {
throw new UnsupportedOperationException("No writing allowed!");
}
@Override
public byte[] getBuffer() {
return buf_;
}
public int getBufferPosition() {
return pos_;
}
public int getBytesRemainingInBuffer() {
return endPos_ - pos_;
}
public void consumeBuffer(int len) {
pos_ += len;
}
}
与 Java NIO 中的 Buffer 类似。
TMemoryBuffer
使用字节数组输出流ByteArrayOutputStream做输出流的封装
public class TMemoryBuffer extends TTransport {
/**
* Create a TMemoryBuffer with an initial buffer size of <i>size</i>. The
* internal buffer will grow as necessary to accommodate the size of the data
* being written to it.
*/
public TMemoryBuffer(int size) {
arr_ = new TByteArrayOutputStream(size);
}
@Override
public boolean isOpen() {
return true;
}
@Override
public void open() {
/* Do nothing */
}
@Override
public void close() {
/* Do nothing */
}
@Override
public int read(byte[] buf, int off, int len) {
byte[] src = arr_.get();
int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len);
if (amtToRead > 0) {
System.arraycopy(src, pos_, buf, off, amtToRead);
pos_ += amtToRead;
}
return amtToRead;
}
@Override
public void write(byte[] buf, int off, int len) {
arr_.write(buf, off, len);
}
/**
* Output the contents of the memory buffer as a String, using the supplied
* encoding
* @param enc the encoding to use
* @return the contents of the memory buffer as a String
*/
public String toString(String enc) throws UnsupportedEncodingException {
return arr_.toString(enc);
}
public String inspect() {
StringBuilder buf = new StringBuilder();
byte[] bytes = arr_.toByteArray();
for (int i = 0; i < bytes.length; i++) {
buf.append(pos_ == i ? "==>" : "" ).append(Integer.toHexString(bytes[i] & 0xff)).append(" ");
}
return buf.toString();
}
// The contents of the buffer
private TByteArrayOutputStream arr_;
// Position to read next byte from
private int pos_;
public int length() {
return arr_.size();
}
public byte[] getArray() {
return arr_.get();
}
}
AutoExpandingBufferReadTransport
AutoExpandingBufferWriteTransport
内部使用可正常的直接数组
AutoExpandingBuffer
AutoExpandingBufferReadTransport
AutoExpandingBufferWriteTransport
TMemoryInputTransport
TByteArrayOutputStream
TMemoryBuffer
内部都是采用直接数组的形式。