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

最近写一个网络下载软件,需要使用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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值