在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. Theskip
method may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly0
. This may result from any of a number of conditions; reaching end of file beforen
bytes have been skipped is only one possibility. The actual number of bytes skipped is returned. Ifn
is negative, no bytes are skipped.The
skip
method of this class creates a byte array and then repeatedly reads into it untiln
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 | 跳过的实际字节数。 |
Throws | IOException: 如果流不支持搜索,或者发生其他 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方法为什么会产生这个问题,需要分析该方法的源码,暂记录于此,等有空了去想一想...