InputStream.skip方法的思考

在java.io.InputStream类中定义了skip这个方法。在API中的描述如下:

skip

public long skip(long n)
          throws IOException
Skips over and discards  n bytes of data from this input stream. The  skip method may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly  0. This may result from any of a number of conditions; reaching end of file before n bytes have been skipped is only one possibility. The actual number of bytes skipped is returned. If  n is negative, no bytes are skipped.

The skip method of this class creates a byte array and then repeatedly reads into it until n bytes have been read or the end of the stream has been reached. Subclasses are encouraged to provide a more efficient implementation of this method. For instance, the implementation may depend on the ability to seek.

Parameters:
n - the number of bytes to be skipped.
Returns:
the actual number of bytes skipped.
Throws:
IOException - if the stream does not support seek, or if some other I/O error occurs.
翻译如下:

skip(long n) throws IOException

跳过和丢弃此输入流中数据的 
n 个字节。出于各种原因,skip 方法结束时跳过的字节数可能小于该数,也可能为 0。导致这种情况的原因很多,跳过 n 个字节之前已到达文件末尾只是其中一种可能。返回跳过的实际字节数。如果 n 为负,则不跳过任何字节。

此类的 skip 方法创建一个 byte 数组,然后重复将字节读入其中,直到读够 n 个字节或已到达流末尾为止。建议子类提供此方法更为有效的实现。例如,可依赖搜索能力的实现。

n
要跳过的字节数。
return
跳过的实际字节数。
ThrowsIOException
如果流不支持搜索,或者发生其他 I/O 错误。


同时,其子类FileInputStream中也继承了skip这个方法。如API中所描述的,skip方法会存在跳过的字节数小于预期的情况。如果不对返回值进行处理的话,很容易忽视这个问题,导致结果错误。最近在看baksmali的源码,其中有一个简单而巧妙的方法来避过skip方法的这个弊端。

 	FileInputStream in = new FileInputStream(file);

        int at = offset;
        while(at > 0) {
            long amt = in.skip(at);
            if (amt == -1) {
                throw new RuntimeException(file + ": unexpected EOF");
            }
            at -= amt;
        }

至于skip方法为什么会产生这个问题,需要分析该方法的源码,暂记录于此,等有空了去想一想...

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值