Java.IO.InputStream.skip() 错误(跳过字节数和预想的不等)

来源:互联网 发布:中国网络资讯台 山寨 编辑:程序博客网 时间:2024/06/05 11:27

最近写一个网络下载软件,需要使用java.IO.InputStream.skip(long n) 方法,它的作用是从输入流中跳过 n 个字节,比如 inputStream.skip(12),就是从inputStream中读最近写一个网络下载软件,需要使用取数据时,跳过前 12 个字节,从第13个字节读取,方法的返回值就是实际跳过的字节数
Java.IO.InputStream.skip(long n)方法,按道理返回值应该等于输入的参数 n (the actual number of bytes skipped.),但是它的我使用的时候,返回值往往小于 n,出错!
Java官方文档指出这个问题,建议自己去写一个方法来实现这个功能(Subclasses are encouraged to provide a more efficient
implementation of this method. For instance, the implementation may depend on the ability to seek),似乎说这个方法能否成功,也要取 决于机器的能力。

其实,如果自己写一个方法,思路就是从头开始读取,等到读到 n 时,再使用,这恰恰就是Java 源码中 InputStream.skip 的思路,一下是自己
写的一个方法:

/*重写了Inpustream 中的skip(long n) 方法,将数据流中起始的n 个字节跳过*/   private long skipBytesFromStream(InputStream inputStream, long n) {    long remaining = n;    // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer    int SKIP_BUFFER_SIZE = 2048;    // skipBuffer is initialized in skip(long), if needed.    byte[] skipBuffer = null;    int nr = 0;    if (skipBuffer == null) {     skipBuffer = new byte[SKIP_BUFFER_SIZE];    }    byte[] localSkipBuffer = skipBuffer;    if (n <= 0) {     return 0;    }    while (remaining > 0) {     try {      nr = inputStream.read(localSkipBuffer, 0,        (int) Math.min(SKIP_BUFFER_SIZE, remaining));     } catch (IOException e) {      e.printStackTrace();     }     if (nr < 0) {      break;     }     remaining -= nr;    }    return n - remaining;   }  

其实这个方法和Java官方源码的skip方法完全一样,只不过多加了一个 InputStream 的参数,当使用 inputStream来跳过 n 个字节时,可以使用这个方法。唯一不明白的就是不知道为什么同样一个方法,放在java 源码中调用会失败,但是自己写的却完全正常,求解…

不过上面的方法一般可以用来读取本地文件,但是如果是从网络下载资源的话,上述方法就根本没有实用性了(比如断点续传)。现在找到一个比较规范的方法:

HttpURLConnection con = null;    try {     con = (HttpURLConnection) u.openConnection();     con.setConnectTimeout(10000);// 设置连接超时为10秒     con.setRequestMethod("GET");     // 设置断点续传得起始与终止位置     long realPos = startPos + pausePos;     con.setRequestProperty("Range", "bytes=" + realPos + "-" + endPos);     con.setUseCaches(true);     InputStream inStream = con.getInputStream();//得到输入流    } catch (Exception exc) {    }  

上面的方法就是使用HTTP来设置一个文件的下载范围(realPos-endPos),这样,从网络向下传输的时候,就会自动从realPos开始传输数据流,一直到endPos为止。

原文地址:http://www.ablanxue.com/prone_7005_1.html

0 0
原创粉丝点击