c2 Streams - Input Stream

read()方法是阻塞的。


什么是native code?


read()一次只能读一个字节,就像write(int b)一次只能写一个字节一样低效,所以有了增强版方法:

public int read(byte b[]) throws IOException { };

public int read(byte b[], int off, int len) throws IOException { };

read一个stream,通常的情况是不能保证一定成功也不能保证就一定失败,通常是你要读1024个字节,但只读了512个,之后网络断了,或者剩下的还在路上, 为了接近这个问题,可以这样:

int bytesRead   = 0;
int bytesToRead = 1024;
byte[] input    = new byte[bytesToRead];
while (bytesRead < bytesToRead) {
  bytesRead += in.read(input, bytesRead, bytesToRead - bytesRead);
}
循环的读,直到完成。

上面的代码有一个bug,没有考虑当数据读完,流返回-1的情况,

int bytesRead = 0;
int bytesToRead = 1024;
byte[] input = new byte[bytesToRead];
while (bytesRead < bytesToRead) {
  int result = in.read(input, bytesRead, bytesToRead - bytesRead);
  if (result == -1) break; // end of stream
  bytesRead += result;
}

如果不想被阻塞到那里一直等,可以用方法available()看下有多少数据可以读了。

int bytesAvailable = in.available();
byte[] input = new byte[bytesAvailable];
int bytesRead = in.read(input, 0, bytesAvailable);
// continue with rest of program immediately...

但,注意,available()返回的值可能是0!如果流到了末尾,available()返回0. 

read(bytes,offset,length) 当流结束时返回-1,可如果本身流的长度是0,那它会返回0.


skip()可以跳过不想读的字节。


File是可以随机访问的,可以跳过任何字节,通过重新定位File pointer,不必每个字节都处理。


通过下面几个方法,可以回退和重新读读过的数据。

public void mark(int readAheadLimit)
public void reset() throws IOException
public boolean markSupported()

mark()当前位置,reset()回到mark的位置,并非每一个stream都支持mark,使用前要markSupported()。

在这里作者吐槽了java的设计,认为很poor,非面向对象,认为应该单独写一个Interface,把这几个方法封装进去,由那些支持mark的stream来实现接口,而非现在的写在abstract base类里面,在使用前要用markSupported()判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值